package org.jeecg.modules.system.app.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.system.app.entity.ReceiptPaymentDetailsInfo;
import org.jeecg.modules.system.app.entity.StatisticsInfo;
import org.jeecg.modules.system.app.entity.StatisticsInfoHis;
import org.jeecg.modules.system.app.mapper.AppOrderMapper;
import org.jeecg.modules.system.app.mapper.StatisticsInfoHisMapper;
import org.jeecg.modules.system.app.mapper.StatisticsInfoMapper;
import org.jeecg.modules.system.app.service.IStatisticsInfoService;
import org.jeecg.modules.system.app.vo.statistics.FindByShopSumVO;
import org.jeecg.modules.system.app.vo.statistics.FindByStatisticsChartVO;
import org.jeecg.modules.system.app.vo.statistics.FindByStatisticsVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.List;

/**
 * @Description: 首页统计表
 * @Author: jeecg-boot
 * @Date:   2025-08-18
 * @Version: V1.0
 */
@Service
public class StatisticsInfoServiceImpl extends ServiceImpl<StatisticsInfoMapper, StatisticsInfo> implements IStatisticsInfoService {

    @Autowired
    StatisticsInfoMapper statisticsInfoMapper;

    @Autowired
    StatisticsInfoHisMapper statisticsInfoHisMapper;

    @Autowired
    AppOrderMapper appOrderMapper;

    @Override
    public Result<String> add(ReceiptPaymentDetailsInfo receiptPaymentDetailsInfo,BigDecimal money) {
        int dateAsInt = Integer.parseInt(
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))
        );
        StatisticsInfo statisticsInfo= statisticsInfoMapper.findByOrgCode(receiptPaymentDetailsInfo.getOrgCode(),dateAsInt);
        if (statisticsInfo==null){
            statisticsInfo =  new StatisticsInfo();
            BeanUtils.copyProperties(receiptPaymentDetailsInfo,statisticsInfo);
            statisticsInfo.setDateDaily(dateAsInt);
        }else {
            StatisticsInfoHis statisticsInfoHis = new StatisticsInfoHis();
            BeanUtils.copyProperties(statisticsInfo,statisticsInfoHis);
            statisticsInfoHis.setCreateTime(new Date());
            statisticsInfoHis.setUpdateTime(new Date());
            int insert = statisticsInfoHisMapper.insert(statisticsInfoHis);
            if (insert!=1){
                throw new JeecgBootException("报错首页统计历史错误,保存失败");
            }

        }
        if (receiptPaymentDetailsInfo.getPayType()==0){
            statisticsInfo.setConsumeNumber(statisticsInfo.getConsumeNumber()+1);
            statisticsInfo.setSaleMoney(statisticsInfo.getSaleMoney().add(money));
            statisticsInfo.setExpectIncomeMoney(statisticsInfo.getExpectIncomeMoney().add(receiptPaymentDetailsInfo.getChangeMoney()));
            statisticsInfo.setEffectiveOrderNum(statisticsInfo.getEffectiveOrderNum()+1);
        }else if (receiptPaymentDetailsInfo.getPayType()==1){
            statisticsInfo.setEffectiveOrderNum(statisticsInfo.getEffectiveOrderNum()-1);
            statisticsInfo.setSaleMoney(statisticsInfo.getSaleMoney().subtract(money));
            statisticsInfo.setExpectIncomeMoney(statisticsInfo.getExpectIncomeMoney().subtract(receiptPaymentDetailsInfo.getChangeMoney()));
        }
        statisticsInfo.setUpdateTime(new Date());
        statisticsInfo.setReceipPaymentDetailsId(receiptPaymentDetailsInfo.getId());
        return Result.ok("成功");
    }

    @Override
    public StatisticsInfo findByCode(String orgCode) {
        return statisticsInfoMapper.findByCode(orgCode);
    }

    @Override
    public FindByStatisticsVO findByStatistics(String orgCode, int dateAsInt, int firstDayInt,int yesterdayNum ) {
        StatisticsInfo byOrgCode = statisticsInfoMapper.findByOrgCode(orgCode, dateAsInt);
        FindByStatisticsVO findByStatisticsVO =new FindByStatisticsVO();
        if(byOrgCode!=null){
            BeanUtils.copyProperties(byOrgCode,findByStatisticsVO);
        }
        // 定义日期格式（yyyyMMdd）
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        List<FindByStatisticsChartVO>    findByStatisticsChartVOS = statisticsInfoMapper.findByOrgCodeAndDay(orgCode,dateAsInt,firstDayInt);
        for (FindByStatisticsChartVO findByStatisticsChartVO : findByStatisticsChartVOS) {
            Integer dateDaily = findByStatisticsChartVO.getDateDaily();
            // 解析为 LocalDate
            LocalDate date = LocalDate.parse(String.valueOf(dateDaily), formatter);
            findByStatisticsChartVO.setDateDailyDate(date);
        }
        StatisticsInfo byOrgCodeOld = statisticsInfoMapper.findByOrgCode(orgCode, yesterdayNum);
        getStatisticsInfo(byOrgCode,byOrgCodeOld,findByStatisticsVO);
        findByStatisticsVO.setFindByStatisticsChartVOList(findByStatisticsChartVOS);
        return findByStatisticsVO;
    }

    @Override
    public List<FindByStatisticsChartVO> findByShopMoneyList(String orgCode,Integer type) {
        LocalDateTime today = LocalDateTime.now();
        /**获取当天的yyyyMMdd时间格式 int类型*/
        int endTime = Integer.parseInt(
                today.format(DateTimeFormatter.ofPattern("yyyyMMdd"))
        );
        /**获取当月的yyyyMMdd时间格式 int类型*/
        int startTime = Integer.parseInt(today.format(DateTimeFormatter.ofPattern("yyyyMMdd")));//默认当天
        if (type==1){//今日
            startTime = Integer.parseInt(today.format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        } else if (type==2) {//本周
            startTime = Integer.parseInt(today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        }else if (type==3){//本月
            startTime = Integer.parseInt(today.withDayOfMonth(1).format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        }
        return statisticsInfoMapper.findByShopMoneyList(orgCode,startTime,endTime);
    }

    @Override
    public List<FindByShopSumVO> findByShopSumList(String orgCode, Integer type) {
        // 获取当前日期
        LocalDate today = LocalDate.now();
        LocalDateTime endTime = today.plusDays(1).atStartOfDay();
        // 1. 今天 00:00:00
        LocalDateTime startTime =today.atStartOfDay();
        if (type==1){
            // 1. 明天 00:00:00
            startTime = today.plusDays(1).atStartOfDay();
        } else if (type==2) {
            // 2. 本周第一天（周一）00:00:00
            startTime = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY))
                    .atStartOfDay();
        } else if (type==3) {
            // 3. 当月第一天 00:00:00
            startTime = today.with(TemporalAdjusters.firstDayOfMonth())
                    .atStartOfDay();
        }
        return appOrderMapper.findByShopSumList(orgCode,startTime,endTime);
    }

    private void getStatisticsInfo(StatisticsInfo statisticsInfoNew ,StatisticsInfo statisticsInfoOld,FindByStatisticsVO findByStatisticsVO){
        if (statisticsInfoOld!=null){
            if (statisticsInfoNew==null){
                findByStatisticsVO.setSaleMoneyChain(getTwoNum(BigDecimal.valueOf(-1)));
                findByStatisticsVO.setAddNumberChain(getTwoNum(BigDecimal.valueOf(-1)));
                findByStatisticsVO.setConsumeNumberChain(getTwoNum(BigDecimal.valueOf(-1)));
                findByStatisticsVO.setEffectiveOrderNumChain(getTwoNum(BigDecimal.valueOf(-1)));
                findByStatisticsVO.setExpectIncomeMoneyChain(getTwoNum(BigDecimal.valueOf(-1)));
            }else {
                findByStatisticsVO.setAddNumberChain(getChain(statisticsInfoNew.getAddNumber(),statisticsInfoOld.getAddNumber()));
                findByStatisticsVO.setConsumeNumberChain(getChain(statisticsInfoNew.getConsumeNumber(),statisticsInfoOld.getConsumeNumber()));
                findByStatisticsVO.setSaleMoneyChain(getChain(statisticsInfoNew.getSaleMoney(),statisticsInfoOld.getSaleMoney()));
                findByStatisticsVO.setEffectiveOrderNumChain(getChain(statisticsInfoNew.getEffectiveOrderNum(),statisticsInfoOld.getEffectiveOrderNum()));
                findByStatisticsVO.setExpectIncomeMoneyChain(getChain(statisticsInfoNew.getExpectIncomeMoney(),statisticsInfoOld.getExpectIncomeMoney()));
            }
        }
    }

    /**
     * 保存两位小数
     * @param bigDecimal
     * @return
     */
    private BigDecimal getTwoNum(BigDecimal bigDecimal){
        if (bigDecimal==null){
            return BigDecimal.ZERO;
        }
        return bigDecimal.multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * 获取环比
     * @param bigDecimalNew
     * @param bigDecimalOld
     * @return
     */
    private BigDecimal getChain(BigDecimal bigDecimalNew,BigDecimal bigDecimalOld){
        if (bigDecimalOld.compareTo(BigDecimal.ZERO)==0){
            return null;
        }
        return getTwoNum((bigDecimalNew.subtract(bigDecimalOld)).divide(bigDecimalOld, 2, RoundingMode.HALF_UP));
    }

    /**
     * 获取环比
     * @param bigDecimalNew
     * @param bigDecimalOld
     * @return
     */
    private BigDecimal getChain(int bigDecimalNew,int bigDecimalOld){
        if (bigDecimalOld==0){
            return null;
        }
        return getChain(BigDecimal.valueOf(bigDecimalNew),BigDecimal.valueOf(bigDecimalOld));
    }

}
