package com.ruoyi.dashboard.service;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.dashboard.domain.dto.BusinessStatisticsQuery;
import com.ruoyi.dashboard.domain.vo.BusinessStatisticsVO;
import com.ruoyi.dashboard.domain.vo.TodoListVO;
import com.ruoyi.dashboard.mapper.DashboardMapper;
import com.ruoyi.ss.abnormal.domain.AbnormalQuery;
import com.ruoyi.ss.abnormal.domain.enums.AbnormalStatus;
import com.ruoyi.ss.abnormal.service.AbnormalService;
import com.ruoyi.ss.bonus.domain.BonusQuery;
import com.ruoyi.ss.bonus.domain.enums.BonusArrivalType;
import com.ruoyi.ss.bonus.domain.vo.BonusDailyAmountVO;
import com.ruoyi.ss.bonus.service.BonusService;
import com.ruoyi.ss.complaint.domain.SmComplaintQuery;
import com.ruoyi.ss.complaint.service.ISmComplaintService;
import com.ruoyi.dashboard.domain.dto.ServiceIncomeQuery;
import com.ruoyi.dashboard.domain.vo.ServiceIncomeVO;
import com.ruoyi.ss.device.domain.DeviceQuery;
import com.ruoyi.ss.device.service.DeviceService;
import com.ruoyi.ss.mchApply.domain.MchApplyQuery;
import com.ruoyi.ss.mchApply.domain.enums.MchApplyStatus;
import com.ruoyi.ss.mchApply.service.IMchApplyService;
import com.ruoyi.ss.receiveBill.domain.ReceiveBillQuery;
import com.ruoyi.ss.receiveBill.domain.enums.ReceiveBillGroupBy;
import com.ruoyi.ss.receiveBill.domain.enums.ReceiveBillType;
import com.ruoyi.ss.receiveBill.domain.vo.ReceiveAmountVO;
import com.ruoyi.ss.receiveBill.service.ReceiveBillService;
import com.ruoyi.ss.riskInfo.domain.RiskInfoQuery;
import com.ruoyi.ss.riskInfo.domain.enums.RiskInfoStatus;
import com.ruoyi.ss.riskInfo.service.RiskInfoService;
import com.ruoyi.ss.storeApply.domain.StoreApplyQuery;
import com.ruoyi.ss.storeApply.domain.enums.StoreApplyStatus;
import com.ruoyi.ss.storeApply.service.StoreApplyService;
import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillGroupBy;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillType;
import com.ruoyi.ss.transactionBill.domain.vo.TransactionAmountVO;
import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author wjh
 * 2024/8/6
 */
@Service
public class DashboardService {

    @Autowired
    private DashboardMapper dashboardMapper;

    @Autowired
    private TransactionBillService transactionBillService;

    @Autowired
    private IMchApplyService mchApplyService;

    @Autowired
    private AbnormalService abnormalService;

    @Autowired
    private ISmComplaintService complaintService;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private StoreApplyService storeApplyService;

    @Autowired
    private ReceiveBillService receiveBillService;

    @Autowired
    private BonusService bonusService;

    @Autowired
    private RiskInfoService riskInfoService;

    public TodoListVO getTodoList() {
        TodoListVO vo = new TodoListVO();

        // 提现申请数量
        TransactionBillQuery withdrawQuery = new TransactionBillQuery();
        withdrawQuery.setType(TransactionBillType.WITHDRAW.getType());
        withdrawQuery.setStatus(TransactionBillStatus.WITHDRAW_APPROVING.getStatus());
        vo.setWithdrawCount(transactionBillService.selectSimpleCount(withdrawQuery));

        // 商户合作申请
        MchApplyQuery mchApplyQuery = new MchApplyQuery();
        mchApplyQuery.setStatus(MchApplyStatus.APPROVING.getStatus());
        vo.setMchApplyCount(mchApplyService.selectCount(mchApplyQuery));

        // 店铺申请
        StoreApplyQuery storeApplyQuery = new StoreApplyQuery();
        storeApplyQuery.setStatus(StoreApplyStatus.WAIT_AUDIT.getStatus());
        vo.setStoreApplyCount(storeApplyService.selectCount(storeApplyQuery));

        // 设备故障
        AbnormalQuery abnormalQuery = new AbnormalQuery();
        abnormalQuery.setStatus(AbnormalStatus.UNREAD.getStatus());
        vo.setAbnormalCount(abnormalService.selectCount(abnormalQuery));

        // 投诉意见
        vo.setComplaintCount(complaintService.selectCount(new SmComplaintQuery()));

        // 过期设备
        DeviceQuery deviceQuery = new DeviceQuery();
        deviceQuery.setIsArrears(true);
        vo.setArrearsDeviceCount(deviceService.selectCount(deviceQuery));

        // 风控审核
        RiskInfoQuery riskInfoQuery = new RiskInfoQuery();
        riskInfoQuery.setStatus(RiskInfoStatus.WAIT_VERIFY.getStatus());
        vo.setRiskVerifyCount(riskInfoService.selectCount(riskInfoQuery));

        return vo;
    }

    public List<ServiceIncomeVO> getServiceIncome(ServiceIncomeQuery query) {

        // 查询服务费
        BonusQuery bonusQuery = new BonusQuery();
        bonusQuery.setPayDateStart(query.getStartDate());
        bonusQuery.setPayDateEnd(query.getEndDate());
        bonusQuery.setArrivalType(BonusArrivalType.PLATFORM.getType());
        List<BonusDailyAmountVO> bonusList = bonusService.selectDailyAmount(bonusQuery);

        // 查询订单
        TransactionBillQuery billQuery = new TransactionBillQuery();
        billQuery.setStartDate(query.getStartDate());
        billQuery.setEndDate(query.getEndDate());
        billQuery.setStatusList(TransactionBillStatus.serviceIncome());
        billQuery.setType(TransactionBillType.RECHARGE.getType());
        List<TransactionAmountVO<Date>> amountList = transactionBillService.selectCommonSumOfMoney(billQuery, TransactionBillGroupBy.create_date.name());

        // 查询提现
        billQuery.setType(TransactionBillType.WITHDRAW.getType());
        List<TransactionAmountVO<Date>> withdrawList = transactionBillService.selectCommonSumOfMoney(billQuery, TransactionBillGroupBy.create_date.name());

        // 查询月费收入
        ReceiveBillQuery receiveQuery = new ReceiveBillQuery();
        receiveQuery.setStartDate(query.getStartDate());
        receiveQuery.setEndDate(query.getEndDate());
        receiveQuery.setType(ReceiveBillType.MONTH.getType());
        List<ReceiveAmountVO<Date>> receiveList = receiveBillService.selectCommonSumOfAmount(receiveQuery, ReceiveBillGroupBy.create_date.name());

        // 查询订单手机号收入
        receiveQuery.setType(ReceiveBillType.MOBILE.getType());
        List<ReceiveAmountVO<Date>> mobileList = receiveBillService.selectCommonSumOfAmount(receiveQuery, ReceiveBillGroupBy.create_date.name());

        // 拼接结果集
        List<ServiceIncomeVO> result = new ArrayList<>();
        if (query.getStartDate() != null && query.getEndDate() != null) {
            result = CollectionUtils.fillVoids(result, ServiceIncomeVO::getDate, (date) -> {
                ServiceIncomeVO vo = new ServiceIncomeVO();
                vo.setDate(date);

                // 订单服务费
                BonusDailyAmountVO bonus = bonusList.stream()
                        .filter(item -> item.getKey().isEqual(date))
                        .findFirst().orElse(null);
                if (bonus != null) {
                    vo.setServiceAmount(bonus.getSum());
                } else {
                    vo.setServiceAmount(BigDecimal.ZERO);
                }

                // 渠道成本
                TransactionAmountVO<Date> transaction = amountList.stream()
                        .filter(item -> item.getKey().compareTo(DateUtils.toDate(date)) == 0)
                        .findFirst().orElse(null);
                if (transaction != null) {
                    vo.setChannelCost(transaction.getChannelCost());
                } else {
                    vo.setChannelCost(BigDecimal.ZERO);
                }

                // 提现服务费收入及成本
                TransactionAmountVO<Date> withdraw = withdrawList.stream()
                        .filter(item -> item.getKey().compareTo(DateUtils.toDate(date)) == 0)
                        .findFirst().orElse(null);
                if (withdraw != null) {
                    vo.setWithdrawServiceAmount(withdraw.getServiceAmount());
                    vo.setChannelCost(vo.getChannelCost().add(withdraw.getChannelCost()));
                } else {
                    vo.setWithdrawServiceAmount(BigDecimal.ZERO);
                }

                // 月费收入
                ReceiveAmountVO<Date> receive = receiveList.stream()
                        .filter(item -> item.getKey().compareTo(DateUtils.toDate(date)) == 0)
                        .findFirst()
                        .orElse(null);
                if (receive != null) {
                    vo.setMonthAmount(receive.getReceivedAmount());
                } else {
                    vo.setMonthAmount(BigDecimal.ZERO);
                }

                // 订单手机号收入
                ReceiveAmountVO<Date> mobile = mobileList.stream()
                        .filter(item -> item.getKey().compareTo(DateUtils.toDate(date)) == 0)
                        .findFirst()
                        .orElse(null);
                if (mobile != null) {
                    vo.setBillMobileAmount(mobile.getReceivedAmount());
                } else {
                    vo.setBillMobileAmount(BigDecimal.ZERO);
                }

                return vo;
            }, query.getStartDate(), query.getEndDate());
        }
        return result;
    }

    public List<BusinessStatisticsVO> businessStatisticsByStore(BusinessStatisticsQuery query) {
        query.setBillType(TransactionBillType.RECHARGE.getType());
        query.setBillStatusList(TransactionBillStatus.payedOrder());
        return dashboardMapper.selectBusinessStatisticsByStore(query);
    }


    public List<BusinessStatisticsVO> businessStatisticsByDevice(BusinessStatisticsQuery query) {
        query.setBillType(TransactionBillType.RECHARGE.getType());
        query.setBillStatusList(TransactionBillStatus.payedOrder());
        return dashboardMapper.selectBusinessStatisticsByDevice(query);
    }
}
