package com.ghy.quartz.service.impl;

import com.ghy.common.enums.FinancialDetailType;
import com.ghy.common.enums.OrderStatus;
import com.ghy.order.domain.OrderDetail;
import com.ghy.order.domain.OrderMaster;
import com.ghy.order.service.OrderDetailService;
import com.ghy.order.service.OrderMasterService;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.OrderFineRecord;
import com.ghy.payment.mapper.OrderFineRecordMapper;
import com.ghy.payment.service.FinancialDetailService;
import com.ghy.quartz.service.OrderService;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {

    private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);
    /**
     * 一小时的毫秒数
     */
    private static final long HOUR_TIME_MILLIS = 60 * 60 * 1000L;
    /**
     * 超时罚金2元
     */
    private static final BigDecimal TIMEOUT_MONEY = BigDecimal.valueOf(2);

    /**
     * 需要超时扣款的订单状态
     */
    @Value("${order.timeout.status:-4,-3,-2,1,2,3}")
    private List<Integer> timeoutOrderStatus;

    @Resource
    private ThreadPoolTaskExecutor executor;
    @Resource
    private OrderMasterService orderMasterService;
    @Resource
    private OrderDetailService orderDetailService;
    @Resource
    private OrderFineRecordMapper orderFineRecordMapper;
    @Resource
    private FinancialDetailService financialDetailService;

    @Override
    public void overTimeOrder(String orderStatus) {
        LocalDateTime now = LocalDateTime.now();
        int nowDay = now.getDayOfMonth();
        int nowHour = now.getHour();
        if (nowHour > 17 || nowHour < 9) {
            // 如果处于休息时间 定时任务不执行
            return;
        }

        // 查询符合超时的单
        List<OrderDetail> orders = orderDetailService.selectByStatus(timeoutOrderStatus);
        for (OrderDetail order : orders) {
            Date updateTime = order.getUpdateTime();
            Calendar instance = Calendar.getInstance();
            instance.setTime(updateTime);
            if (instance.get(Calendar.DAY_OF_MONTH) == nowDay) {
                // 如果订单更新的时间是今天
                if (System.currentTimeMillis() - updateTime.getTime() > HOUR_TIME_MILLIS * 4) {
                    // 并且距离上一次更新时间已经超过4h 则判定超时
                    executor.execute(() -> orderTimeout(order));
                }
            } else {
                // 如果订单更新的时间不是今天
                if (System.currentTimeMillis() - updateTime.getTime() > HOUR_TIME_MILLIS * 19) {
                    // 并且距离上一次更新时间已经超过15h 则判定超时
                    executor.execute(() -> orderTimeout(order));
                }
            }
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void orderTimeout(OrderDetail order) {
        // 查询扣款记录 如果已经扣过了 就不处理了
        OrderFineRecord orderFineRecord = new OrderFineRecord(order.getId(), 1, order.getOrderStatus());
        List<OrderFineRecord> records = orderFineRecordMapper.selectList(orderFineRecord);
        if (!CollectionUtils.isEmpty(records)) {
            return;
        }

        // 保存一条扣款记录
        orderFineRecordMapper.insert(orderFineRecord);

        // 从子订单对应的财务单里扣除2元
        FinancialDetail orderFinancial = financialDetailService.selectByOrderDetailId(order.getId());
        orderFinancial.setPayMoney(orderFinancial.getPayMoney().subtract(TIMEOUT_MONEY));
        financialDetailService.updateFinancialDetail(orderFinancial);

        // 生成对应的扣款明细
        FinancialDetail fineFinancial = new FinancialDetail();
        fineFinancial.setDeptId(orderFinancial.getDeptId());
        fineFinancial.setCode(financialDetailService.createCode());
        fineFinancial.setFinancialMasterId(orderFinancial.getFinancialMasterId());
        fineFinancial.setFinancialMasterCode(orderFinancial.getFinancialMasterCode());
        fineFinancial.setPayMoney(TIMEOUT_MONEY);
        fineFinancial.setFinancialDetailType(FinancialDetailType.FINE_FEE.getCode());
        financialDetailService.insertFinancialDetail(fineFinancial);
    }


    @Override
    public void finishOrder() {
        // 查询出"待确认"状态的子订单
        List<OrderDetail> orderDetails = orderDetailService.selectByStatus(Collections.singletonList(OrderStatus.FINISH_CHECK.code()));
        long now = System.currentTimeMillis();
        long day14ago = now - (14 * 24 * 60 * 60 * 1000L);
        for (OrderDetail orderDetail : orderDetails) {
            // 查询符合自动确认的订单
            if (day14ago > orderDetail.getUpdateTime().getTime()) {
                logger.info("订单自动完成[id={}, code={}]", orderDetail.getId(), orderDetail.getCode());
                try {
                    // 完单流程(分账与提现)
                    orderDetailService.finish(orderDetail.getId());
                } catch (BaseAdaPayException e) {
                    logger.error("订单自动完成[id={}, code={}]出错", orderDetail.getId(), orderDetail.getCode(), e);
                }
            }
        }

        // 当所有的子订单完成后 自动把主订单完成
        List<OrderMaster> orderMasters = orderMasterService.selectUnfinished();
        for (OrderMaster orderMaster : orderMasters) {
            executor.execute(() -> {
                try {
                    orderMasterService.finish(orderMaster.getId());
                }catch (Exception e){
                    logger.error("主订单 Finish 失败", e);
                }
            });
        }
    }
}
