package com.ruoyi.bst.store.service.impl;

import com.ruoyi.bst.device.domain.DeviceCountVO;
import com.ruoyi.bst.order.domain.OrderQuery;
import com.ruoyi.bst.order.domain.enums.OrderStatus;
import com.ruoyi.bst.order.service.OrderService;
import com.ruoyi.bst.pay.domain.PayQuery;
import com.ruoyi.bst.pay.domain.enums.PayStatus;
import com.ruoyi.bst.pay.service.PayService;
import com.ruoyi.common.domain.vo.LongDecimalVO;
import com.ruoyi.common.domain.vo.LongIntegerVO;
import com.ruoyi.common.utils.collection.CollectionUtils;

import com.ruoyi.bst.device.domain.DeviceQuery;
import com.ruoyi.bst.device.domain.enums.DeviceGroupBy;
import com.ruoyi.bst.device.domain.enums.DeviceOnlineStatus;
import com.ruoyi.bst.device.domain.enums.DeviceStatus;
import com.ruoyi.bst.device.service.DeviceService;
import com.ruoyi.bst.refund.domain.RefundQuery;
import com.ruoyi.bst.refund.domain.enums.RefundStatus;
import com.ruoyi.bst.refund.service.RefundService;
import com.ruoyi.bst.store.domain.StoreVO;
import com.ruoyi.bst.store.service.StoreAssembler;
import com.ruoyi.bst.store.service.StoreValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author wjh
 *         2024/4/29
 */
@Service
public class StoreAssemblerImpl implements StoreAssembler {

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private StoreValidator storeValidator;


    @Autowired
    private RefundService refundService;


    @Autowired
    private PayService payService;
    @Autowired
    private OrderService orderService;

    /**
     * 拼接设备数量
     *
     * @param list 店铺列表
     */
    @Override
    public void assembleDeviceCount(List<StoreVO> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return;
        }
        // 设备总数量
        this.assembleTotalCount(list);
        // 在线设备数量
        this.assembleOnlineCount(list);
        // 离线设备数量
        this.assembleOfflineCount(list);
        // 设备状态数量
        //this.assembleDeviceStatus(list);
    }



    /**
     * 拼接营收数据
     *
     * @param list
     */
    @Override
    public void assembleRevenue(List<StoreVO> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return;
        }
        // 本日订单金额
        this.assembleTodayIncome(list);
        // 总订单金额
        this.assembleTotalIncome(list);
        // 本日订单量
        this.assembleTodayOrderCount(list);
        // 总订单量
        this.assembleTotalOrderCount(list);
        // 总用户量
        this.assembleTotalUserCount(list);
        // 本月收入
        this.assembleMonthIncome(list);
        // 上月收入
        this.assembleLastMonthIncome(list);
    }

    /**
     * 拼接设备状态数量
     *
     * @param list
     */
//    public void assembleDeviceStatus(List<StoreVO> list) {
//        if (CollectionUtils.isEmptyElement(list)) {
//            return;
//        }
//        // 查询设备状态数量，并按店铺、状态分组
//        DeviceQuery query = new DeviceQuery();
//        query.setStoreIds(CollectionUtils.map(list, StoreVO::getStoreId));
//        List<Map<String, Object>> countList = deviceDashboardService.selectCountGroupBy(query, Arrays.asList("sd.store_id", "sd.status"));
//
//        for (StoreVO store : list) {
//            Map<String, Object> countMap = countList.stream()
//                .filter(item -> Objects.equals(item.get("store_id"), store.getStoreId()))
//                .collect(Collectors.toMap(item -> item.get("status").toString(), item -> item.get("count")));
//            if (countMap != null) {
//                store.setDeviceStatusMap(countMap);
//            }
//        }
//    }


    /**
     * 拼接本日订单量
     *
     * @param list
     */
    public void assembleTodayOrderCount(List<StoreVO> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return;
        }
        LocalDate now = LocalDate.now();

        // 查询订单量
        OrderQuery query = new OrderQuery();
        query.setStoreIds(CollectionUtils.map(list, StoreVO::getStoreId));
        query.setStatusList(OrderStatus.payed());
        query.setCreateDate(now);
        Map<Long, Integer> countMap = orderService.selectCountGroupByStoreId(query)
                .stream().collect(Collectors.toMap(LongIntegerVO::getKey, LongIntegerVO::getValue));

        for (StoreVO store : list) {
            Integer count = countMap.get(store.getStoreId());
            store.setTodayOrderCount(count == null ? 0 : count);
        }
    }

    /**
     * 拼接总订单量
     *
     * @param list
     */
    public void assembleTotalOrderCount(List<StoreVO> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return;
        }

        // 查询订单量
        OrderQuery query = new OrderQuery();
        query.setStoreIds(CollectionUtils.map(list, StoreVO::getStoreId));
        query.setStatusList(OrderStatus.payed());
        Map<Long, Integer> countMap = orderService.selectCountGroupByStoreId(query)
                .stream().collect(Collectors.toMap(LongIntegerVO::getKey, LongIntegerVO::getValue));

        for (StoreVO store : list) {
            Integer count = countMap.get(store.getStoreId());
            store.setTotalOrderCount(count == null ? 0 : count);
        }
    }

    /**
     * 拼接总用户量
     *
     * @param list
     */
    public void assembleTotalUserCount(List<StoreVO> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return;
        }

        // 查询用户量
        OrderQuery query = new OrderQuery();
        query.setStoreIds(CollectionUtils.map(list, StoreVO::getStoreId));
        Map<Long, Integer> countMap = orderService.selectCountGroupByStoreId(query)
                .stream().collect(Collectors.toMap(LongIntegerVO::getKey, LongIntegerVO::getValue));

        for (StoreVO store : list) {
            Integer count = countMap.get(store.getStoreId());
            store.setTotalUserCount(count == null ? 0 : count);
        }
    }


    /**
     * 拼接本月收入
     *
     * @param list
     */
    @Override
    public void assembleMonthIncome(List<StoreVO> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return;
        }

        // 查询支付信息
        PayQuery query = new PayQuery();
        LocalDate now = LocalDate.now();
        query.setStoreIds(CollectionUtils.map(list, StoreVO::getStoreId));
        query.setStatusList(PayStatus.payedList());
        query.setPayMonth(now.getMonthValue());
        query.setPayYear(now.getYear());
        Map<Long, BigDecimal> payMap = payService.selectSumOfAmountGroupByStoreId(query)
                .stream().collect(Collectors.toMap(LongDecimalVO::getKey, LongDecimalVO::getValue));

        // 查询退款信息
        RefundQuery refundQuery = new RefundQuery();
        refundQuery.setStoreIds(CollectionUtils.map(list, StoreVO::getStoreId));
        refundQuery.setMonth(now.getMonthValue());
        refundQuery.setYear(now.getYear());
        refundQuery.setStatusList(RefundStatus.successList());
        Map<Long, BigDecimal> refundMap = refundService.selectSumOfRefundAmountGroupByStoreId(refundQuery)
                .stream().collect(Collectors.toMap(LongDecimalVO::getKey, LongDecimalVO::getValue));

        for (StoreVO store : list) {
            BigDecimal monthIncome = payMap.get(store.getStoreId());
            BigDecimal refundAmount = refundMap.get(store.getStoreId());
            if (monthIncome == null) {
                monthIncome = BigDecimal.ZERO;
            }
            if (refundAmount != null) {
                monthIncome = monthIncome.subtract(refundAmount);
            }
            store.setMonthRefundAmount(refundAmount);
            store.setMonthIncome(monthIncome);
        }
    }

    /**
     * 拼接本日收入
     *
     * @param list
     */
    @Override
    public void assembleTodayIncome(List<StoreVO> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return;
        }
        LocalDate now = LocalDate.now();

        // 查询支付信息
        PayQuery query = new PayQuery();
        query.setStoreIds(CollectionUtils.map(list, StoreVO::getStoreId));
        query.setStatusList(PayStatus.payedList());
        query.setPayDate(now);
        Map<Long, BigDecimal> payMap = payService.selectSumOfAmountGroupByStoreId(query)
                .stream().collect(Collectors.toMap(LongDecimalVO::getKey, LongDecimalVO::getValue));

        // 查询退款信息
        RefundQuery refundQuery = new RefundQuery();
        refundQuery.setStoreIds(CollectionUtils.map(list, StoreVO::getStoreId));
        refundQuery.setCreateDate(now);
        refundQuery.setStatusList(RefundStatus.successList());
        Map<Long, BigDecimal> refundMap = refundService.selectSumOfRefundAmountGroupByStoreId(refundQuery)
                .stream().collect(Collectors.toMap(LongDecimalVO::getKey, LongDecimalVO::getValue));

        for (StoreVO store : list) {
            BigDecimal todayIncome = payMap.get(store.getStoreId());
            BigDecimal refundAmount = refundMap.get(store.getStoreId());
            // 订单金额
            if (todayIncome == null) {
                todayIncome = BigDecimal.ZERO;
            }
            // 退款金额
            if (refundAmount == null) {
                refundAmount = BigDecimal.ZERO;
            }
            store.setTodayRefundAmount(refundAmount);
            store.setTodayIncome(todayIncome.subtract(refundAmount));
        }
    }

    /**
     * 拼接总订单金额
     *
     * @param list
     */
    public void assembleTotalIncome(List<StoreVO> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return;
        }

        // 查询支付信息
        PayQuery query = new PayQuery();
        query.setStoreIds(CollectionUtils.map(list, StoreVO::getStoreId));
        query.setStatusList(PayStatus.payedList());
        Map<Long, BigDecimal> payMap = payService.selectSumOfAmountGroupByStoreId(query)
                .stream().collect(Collectors.toMap(LongDecimalVO::getKey, LongDecimalVO::getValue));

        // 查询退款信息
        RefundQuery refundQuery = new RefundQuery();
        refundQuery.setStoreIds(CollectionUtils.map(list, StoreVO::getStoreId));
        refundQuery.setStatusList(RefundStatus.successList());
        Map<Long, BigDecimal> refundMap = refundService.selectSumOfRefundAmountGroupByStoreId(refundQuery)
                .stream().collect(Collectors.toMap(LongDecimalVO::getKey, LongDecimalVO::getValue));

        for (StoreVO store : list) {
            BigDecimal totalAmount = payMap.get(store.getStoreId());
            BigDecimal refundAmount = refundMap.get(store.getStoreId());
            // 订单金额
            if (totalAmount == null) {
                totalAmount = BigDecimal.ZERO;
            }
            // 退款金额
            if (refundAmount == null) {
                refundAmount = BigDecimal.ZERO;
            }
            store.setTotalIncome(totalAmount.subtract(refundAmount));
        }
    }

    /**
     * 拼接上月收入
     *
     * @param list
     */
    @Override
    public void assembleLastMonthIncome(List<StoreVO> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return;
        }
        // 上月
        LocalDate lastMonth = LocalDate.now().plusMonths(-1);

        // 查询支付信息
        PayQuery query = new PayQuery();
        query.setStoreIds(CollectionUtils.map(list, StoreVO::getStoreId));
        query.setStatusList(PayStatus.payedList());
        query.setPayMonth(lastMonth.getMonthValue());
        query.setPayYear(lastMonth.getYear());
        Map<Long, BigDecimal> payMap = payService.selectSumOfAmountGroupByStoreId(query)
                .stream().collect(Collectors.toMap(LongDecimalVO::getKey, LongDecimalVO::getValue));

        // 查询退款信息
        RefundQuery refundQuery = new RefundQuery();
        refundQuery.setStoreIds(CollectionUtils.map(list, StoreVO::getStoreId));
        refundQuery.setMonth(lastMonth.getMonthValue());
        refundQuery.setYear(lastMonth.getYear());
        refundQuery.setStatusList(RefundStatus.successList());
        Map<Long, BigDecimal> refundMap = refundService.selectSumOfRefundAmountGroupByStoreId(refundQuery)
                .stream().collect(Collectors.toMap(LongDecimalVO::getKey, LongDecimalVO::getValue));

        for (StoreVO store : list) {
            BigDecimal lastMonthIncome = payMap.get(store.getStoreId());
            BigDecimal refundAmount = refundMap.get(store.getStoreId());
            if (lastMonthIncome == null) {
                lastMonthIncome = BigDecimal.ZERO;
            }
            if (refundAmount != null) {
                lastMonthIncome = lastMonthIncome.subtract(refundAmount);
            }
            store.setLastMonthRefundAmount(refundAmount);
            store.setLastMonthIncome(lastMonthIncome);
        }
    }


    /**
     * 拼接设备总数
     * @param list
     */
    @Override
    public void assembleTotalCount(List<StoreVO> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return;
        }
        DeviceQuery query = new DeviceQuery();
        query.setStoreIds(list.stream().map(StoreVO::getStoreId).collect(Collectors.toList()));
        Map<Long,Integer> countMap = deviceService.selectCommonCountMap(query)
                .stream().collect(Collectors.toMap(LongIntegerVO::getKey, LongIntegerVO::getValue));

        for (StoreVO store : list) {
            Integer count = countMap.get(store.getStoreId());
            store.setDeviceCount(count == null ? 0 : count);
        }
    }

    /**
     * 拼接在线数量
     *
     * @param list
     */
    @Override
    public void assembleOnlineCount(List<StoreVO> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return;
        }
        DeviceQuery query = new DeviceQuery();
        query.setStoreIds(list.stream().map(StoreVO::getStoreId).collect(Collectors.toList()));
        query.setOnlineStatus(DeviceOnlineStatus.ONLINE.getStatus());
        Map<Long,Integer> countMap = deviceService.selectCommonCountMap(query)
                .stream().collect(Collectors.toMap(LongIntegerVO::getKey, LongIntegerVO::getValue));

        for (StoreVO store : list) {
            Integer count = countMap.get(store.getStoreId());
            store.setOnlineCount(count == null ? 0 : count);
        }
    }

    /**
     * 拼接离线数量
     *
     * @param list
     */
    @Override
    public void assembleOfflineCount(List<StoreVO> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return;
        }
        DeviceQuery query = new DeviceQuery();
        query.setStoreIds(list.stream().map(StoreVO::getStoreId).collect(Collectors.toList()));
        query.setOnlineStatus(DeviceOnlineStatus.OFFLINE.getStatus());
        Map<Long,Integer> countMap = deviceService.selectCommonCountMap(query)
                .stream().collect(Collectors.toMap(LongIntegerVO::getKey, LongIntegerVO::getValue));

        for (StoreVO store : list) {
            Integer count = countMap.get(store.getStoreId());
            store.setOfflineCount(count == null ? 0 : count);
        }
    }

    /**
     * 拼接可共享设备数量
     *
     * @param list
     */
//    @Override
//    public void assembleAvailableDeviceCount(List<StoreVO> list) {
//        if (CollectionUtils.isEmptyElement(list)) {
//            return;
//        }
//        DeviceQuery query = new DeviceQuery();
//        query.setStoreIds(list.stream().map(StoreVO::getStoreId).collect(Collectors.toList()));
//        query.setOnlineStatus(DeviceOnlineStatus.ONLINE.getStatus());
//        query.setStatus(DeviceStatus.NORMAL.getStatus());
//        query.setGroupBy(DeviceGroupBy.store_id.name());
//        Map<Long, Integer> countMap = deviceService.selectCommonCountMap(query, DeviceCountVO::getStoreId);
//
//        for (StoreVO store : list) {
//            Integer count = countMap.get(store.getStoreId());
//            store.setAvailableDeviceCount(count == null ? 0 : count);
//        }
//    }
//
//    @Override
//    public void assembleOperator(List<StoreVO> list, Long userId) {
//        if (CollectionUtils.isEmptyElement(list)) {
//            return;
//        }
//
//        for (StoreVO store : list) {
//            StoreOperatorVO vo = StoreOperatorVO.defaultInstance();
//            // 有操作权限，可修改、配置
//            if (storeValidator.canOperaStore(store, userId)) {
//                vo.setConfig(true);
//                vo.setUpdate(true);
//            }
//            // 是商户，可删除、查看设备列表
//            if (storeValidator.isMch(store, userId)) {
//                vo.setDel(true);
//                vo.setViewDevice(true);
//                vo.setAddStaff(true);
//            }
//            store.setOperator(vo);
//        }
//    }
//
//    @Override
//    public void assembleBonusList(List<StoreVO> list) {
//        if (CollectionUtils.isEmptyElement(list)) {
//            return;
//        }
//
//        // 查询店铺员工列表
//        this.assembleStaffList(list);
//
//        for (StoreVO store : list) {
//            List<Bonus> bonusList = bonusConverter.toPoListByVip(store, store.getStaffList(), true);
//            store.setBonusList(bonusList);
//        }
//    }
//
//    @Override
//    public void assembleStaffList(List<StoreVO> list) {
//        if (CollectionUtils.isEmptyElement(list)) {
//            return;
//        }
//
//        List<StoreStaffVO> staffList = storeStaffService
//                .selectListByStoreIds(CollectionUtils.map(list, StoreVO::getStoreId));
//
//        for (StoreVO store : list) {
//            List<StoreStaffVO> storeStaffList = staffList.stream()
//                    .filter(staff -> Objects.equals(staff.getStoreId(), store.getStoreId()))
//                    .collect(Collectors.toList());
//            store.setStaffList(storeStaffList);
//        }
//    }
//
//    @Override
//    public void assembleApply(List<StoreVO> list) {
//        if (CollectionUtils.isEmptyElement(list)) {
//            return;
//        }
//
//        StoreApplyQuery query = new StoreApplyQuery();
//        query.setIds(CollectionUtils.map(list, StoreVO::getApplyId));
//        List<StoreApplyVO> applyList = storeApplyService.selectStoreApplyList(query);
//
//        for (StoreVO store : list) {
//            StoreApplyVO apply = applyList.stream()
//                    .filter(item -> Objects.equals(item.getId(), store.getApplyId()))
//                    .findFirst()
//                    .orElse(null);
//            store.setApply(apply);
//        }
    //}
}
