package com.iformall.schedule;

import com.iformall.common.IdWorker;
import com.iformall.domain.po.*;
import com.iformall.enums.EnumDateAmtType;
import com.iformall.enums.EnumMerchantStatus;
import com.iformall.mapper.*;
import com.iformall.service.WxDateAmountRecordService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
public class DaliyAmountSchedule {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WxMallMapper wxMallMapper;

    @Autowired
    private WxMerchantMapper wxMerchantMapper;

    @Autowired
    private WxCouponOrderMapper wxCouponOrderMapper;

    @Autowired
    private WxDateAmountRecordService wxDateAmountRecordService;

    @Autowired
    private WxOrderMapper wxOrderMapper;


    @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class})
    public void daliyAmountMerchant(Date startDate,Date endDate,Calendar cal,WxMerchant merchant){
        Map dateMap = new HashMap();
        dateMap.put("startDate", startDate);
        dateMap.put("endDate", endDate);
        dateMap.put("merchantId", merchant.getId());

        List<WxCouponOrder> list = wxCouponOrderMapper.findListOfOrderedByDate(dateMap);
        logger.info("find " + list.size() + " coupon order from " + startDate + " to " + endDate);
        int total_price = list.stream().mapToInt(p -> p.getCouponPrice()).sum();

        logger.info("\nFound " + list.size() + " coupon orders \n" +
                "for merchantId:" + merchant.getId() + "\n" +
                "from " + startDate + " to " + endDate + "\n" +
                "TOTAL ORDER=" + total_price);

        WxDateAmountRecord dateAmountRecord = new WxDateAmountRecord();
        dateAmountRecord.setPayPrice(total_price);
        dateAmountRecord.setMerchantId(merchant.getId());
        dateAmountRecord.setTenantId(merchant.getTenantId());
        dateAmountRecord.setType(EnumDateAmtType.PAY_RECORD.getCode());
        dateAmountRecord.setDate(startDate);
        dateAmountRecord.setDayOfWeek(cal.get(Calendar.DAY_OF_WEEK));
        dateAmountRecord.setMonth(cal.get(Calendar.MONTH));
        dateAmountRecord.setWeekOfYear(cal.get(Calendar.WEEK_OF_YEAR));

        wxDateAmountRecordService.saveAmount(dateAmountRecord);

        list = wxCouponOrderMapper.findListOfVerifiedByDate(dateMap);
        logger.info("\nfind " + list.size() + " coupon order from " + startDate + " to " + endDate);
        total_price = list.stream().mapToInt(p -> p.getCouponPrice()).sum();
        logger.info("\nFound " + list.size() + " coupon orders \n" +
                "for merchantId:" + merchant.getId() + "\n" +
                "from " + startDate + " to " + endDate + "\n" +
                "TOTAL VERIFIED=" + total_price);

        dateAmountRecord.setPayPrice(total_price);
        dateAmountRecord.setType(EnumDateAmtType.VERIFY_RECORD.getCode());
        wxDateAmountRecordService.saveAmount(dateAmountRecord);

        Map microPayMap = wxOrderMapper.dayMicroPayAmountList(dateMap);
        Long countMic = (Long) microPayMap.get("count");
        BigDecimal totalPriceMic = (BigDecimal) microPayMap.get("total_price");
        logger.info("\nFound " + countMic + " order " + "\n" +
                "for merchantId:" + merchant.getId() + "\n" +
                "from " + startDate + " to " + endDate + "\n" +
                "TOTAL Payment=" + totalPriceMic);

        dateAmountRecord.setPayPrice(totalPriceMic.intValue());
        dateAmountRecord.setType(EnumDateAmtType.MICROPAY_RECORD.getCode());
        wxDateAmountRecordService.saveAmount(dateAmountRecord);

    }


    @Scheduled(cron = "0 0 1 * * ?") // 每天凌晨1点盘点前一天的数据
    //@Scheduled(cron = "*/30 * * * * ?") // 测试10秒中一次
    public void daliyAmountSchedule() {
        List<WxMall> mallList = wxMallMapper.findList(new WxMall());

        if (mallList.size()==0) {
            logger.info("No Mall info found");
            return;
        }

        mallList.stream().forEach(mall->{
            WxMerchant merchantQ = new WxMerchant();
            merchantQ.setTenantId(mall.getTenantId());
            merchantQ.setStatus(EnumMerchantStatus.VALID.getCode());
            List<WxMerchant> merchantList = wxMerchantMapper.findList(merchantQ);

            if (merchantList.size()==0) {
                logger.info("No merchant info found in mall" + mall.getName());
                return;
            }

            // 时间选择
            Calendar cal = Calendar.getInstance();
            cal.setTime(new Date());
            cal.set(Calendar.HOUR_OF_DAY, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.SECOND, 0);
            cal.set(Calendar.MILLISECOND, 0);

            int day = 0; //查找过去30天是否有漏记
            do {

                cal.add(Calendar.DAY_OF_YEAR, 0);
                Date endDate = cal.getTime();
                cal.add(Calendar.DAY_OF_YEAR, -1);
                Date startDate = cal.getTime();

                merchantList.stream().filter(merchant->{
                            WxDateAmountRecord dateAmountRecordQ = new WxDateAmountRecord();
                            dateAmountRecordQ.setDate(startDate);
                            dateAmountRecordQ.setMerchantId(merchant.getId());
                            return (wxDateAmountRecordService.listAsPage(dateAmountRecordQ,1,1).getList().size()==0);
                        }).forEach(merchant -> {
                    daliyAmountMerchant(startDate, endDate, cal, merchant);
                });
            } while (day-- > -7); //补全最近7天的数据
        });
    }
}