package com.sckw.report.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.sckw.contract.api.feign.SalesReportContractFeignService;
import com.sckw.core.common.enums.enums.DictTypeEnum;
import com.sckw.core.model.constant.Global;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.core.web.response.BaseResult;
import com.sckw.excel.utils.ExcelUtil;
import com.sckw.order.api.feign.SalesReportOrderFeignService;
import com.sckw.order.api.model.SalesReportDataVo;
import com.sckw.order.api.model.SalesReportQueryDto;
import com.sckw.product.api.dubbo.GoodsInfoService;
import com.sckw.product.api.model.KwpGoods;
import com.sckw.report.model.dto.SalesReportDTO;
import com.sckw.report.model.vo.SalesReportVO;
import com.sckw.report.model.vo.SalesReportSummaryVO;
import com.sckw.report.service.KwSalesReportService;
import com.sckw.system.api.RemoteSystemService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Service
@RequiredArgsConstructor
public class KwSalesReportServiceImpl implements KwSalesReportService {

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Autowired
    private SalesReportContractFeignService salesReportContractFeignService;
    @Autowired
    private SalesReportOrderFeignService salesReportOrderFeignService;
    @DubboReference(version = "1.0.0", group = "design", check = false)
    private GoodsInfoService goodsInfoService;
    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteSystemService remoteSystemService;

    @Override
    public List<SalesReportVO> getSalesReportData(SalesReportDTO salesReportDTO) {
        // 调用订单服务获取销售报表数据
        SalesReportQueryDto queryDto = new SalesReportQueryDto();
        queryDto.setCurEntId(LoginUserHolder.getEntId());
        queryDto.setTradeEntId(salesReportDTO.getTradeEntId());
        queryDto.setGoodsId(salesReportDTO.getGoodsId());

        // 转换时间格式：Date转String yyyy-MM-dd
        if (salesReportDTO.getStartTime() != null) {
            queryDto.setStartTime(sdf.format(salesReportDTO.getStartTime()));
        }
        if (salesReportDTO.getEndTime() != null) {
            queryDto.setEndTime(sdf.format(salesReportDTO.getEndTime()));
        }
        Map<String, Map<String, String>> dict = remoteSystemService.queryDictByType(List.of(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), DictTypeEnum.GOODS_SPEC.getType()));
        Map<String, String> nameMap, specMap;
        if (CollUtil.isNotEmpty(dict)) {
            nameMap = CollUtil.isNotEmpty(dict.get(DictTypeEnum.PRODUCT_NAME_TYPE.getType())) ? dict.get(DictTypeEnum.PRODUCT_NAME_TYPE.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);
            specMap = CollUtil.isNotEmpty(dict.get(DictTypeEnum.GOODS_SPEC.getType())) ? dict.get(DictTypeEnum.GOODS_SPEC.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);

        } else {
            nameMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            specMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        }

        BaseResult<List<SalesReportDataVo>> result = salesReportOrderFeignService.querySalesReportData(queryDto);
        if (result != null && result.isSuccess() && result.getData() != null) {
            List<SalesReportDataVo> salesReportData = result.getData();
            List<Long> goodIdList = salesReportData.stream().map(SalesReportDataVo::getGoodsId).distinct().toList();
            Map<Long, KwpGoods> goodsMap = goodsInfoService.getGoodsByIds(goodIdList);

            // 转换为销售报表VO
            AtomicInteger serialNumber = new AtomicInteger(1);
            return salesReportData.stream().map(data -> {
                SalesReportVO vo = new SalesReportVO();
                KwpGoods goods = goodsMap.get(data.getGoodsId());
                vo.setSerialNumber(serialNumber.getAndIncrement());
                vo.setEntName(data.getCustomerName());
                if (Objects.nonNull(goods)) {
                    String goodsType = nameMap.get(goods.getGoodsType());
                    String spec = specMap.get(goods.getSpec());
                    vo.setGoodsName(goods.getName() + "/" + goodsType + "/" + spec);
                } else {
                    vo.setGoodsName(data.getGoodsName());
                }
                vo.setSalesQuantity(data.getSalesQuantity());
                vo.setAveragePrice(data.getAveragePrice());
                vo.setSalesAmount(data.getSalesAmount());
                vo.setTotalSalesQuantity(data.getCumulativeQuantity());
                vo.setTotalAveragePrice(data.getCumulativeAveragePrice());
                vo.setTotalSalesAmount(data.getCumulativeAmount());
                return vo;
            }).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    @Override
    public SalesReportSummaryVO getSalesReportSummary(SalesReportDTO salesReportDTO) {
        List<SalesReportVO> reportData = getSalesReportData(salesReportDTO);
        SalesReportSummaryVO summary = new SalesReportSummaryVO();

        BigDecimal totalSalesQuantity = BigDecimal.ZERO;
        BigDecimal totalSalesAmount = BigDecimal.ZERO;
        BigDecimal totalTotalSalesQuantity = BigDecimal.ZERO;
        BigDecimal totalTotalSalesAmount = BigDecimal.ZERO;

        for (SalesReportVO vo : reportData) {
            totalSalesQuantity = totalSalesQuantity.add(vo.getSalesQuantity());
            totalSalesAmount = totalSalesAmount.add(vo.getSalesAmount());
            totalTotalSalesQuantity = totalTotalSalesQuantity.add(vo.getTotalSalesQuantity());
            totalTotalSalesAmount = totalTotalSalesAmount.add(vo.getTotalSalesAmount());
        }

        summary.setTotalSalesQuantity(totalSalesQuantity);
        summary.setTotalSalesAmount(totalSalesAmount);
        summary.setTotalTotalSalesQuantity(totalTotalSalesQuantity);
        summary.setTotalTotalSalesAmount(totalTotalSalesAmount);

        return summary;
    }

    @Override
    public void exportSalesReport(SalesReportDTO salesReportDTO, HttpServletResponse response) {
        List<SalesReportVO> reportData = getSalesReportData(salesReportDTO);

        // 导出Excel
        ExcelUtil.download(response, SalesReportVO.class, reportData);
    }
}
