package cn.superdesk.uniorder.service.order.base;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.superdesk.uniorder.common.enums.common.CommonAccountingLockingEnum;
import cn.superdesk.uniorder.common.enums.common.CommonAccountingStateEnum;
import cn.superdesk.uniorder.common.enums.common.CommonOrderTypeEnum;
import cn.superdesk.uniorder.dao.entity.base.*;
import cn.superdesk.uniorder.dao.mapper.base.*;
import cn.superdesk.uniorder.dto.param.operation.UnifiedOrderIssuesFlowingParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * @Description: 退单为主休逻辑
 * @Author: linjinyu
 * @CreateDate: 2021/7/1 下午5:22
 * @UpdateUser: linjinyu
 * @UpdateDate: 2021/7/1 下午5:22
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class CommonMergeRefundOrderProcessService {

    @Autowired
    private UnifiedOrderMapper                    unifiedOrderMapper;
    @Autowired
    private UnifiedOrderMapperEx                  unifiedOrderMapperEx;
    @Autowired
    private UnifiedOrderMapperExCustomerDimCredit unifiedOrderMapperExScore;

    @Autowired
    private UnifiedOrderGoodsMapper  unifiedOrderGoodsMapper;
    @Autowired
    private UnifiedOrderCreditMapper unifiedOrderCreditMapper;


    /**
     * 双主体情况 - 退单作为新主体模式 对标 processScoreOrderRefundUnifiedOrder 差别就是不核算了
     *
     * @param refundOrderPorcess
     * @return
     */
    public UnifiedOrder processScoreOrderRefundUnifiedOrder(UnifiedOrderReturn refundOrderPorcess) {

        UnifiedOrder orderInDd       = unifiedOrderMapperEx.findByOrderSn(refundOrderPorcess.getOrderSn());
        UnifiedOrder refundOrderInDb = unifiedOrderMapperEx.findByOrderSn(refundOrderPorcess.getReturnSn());

        // 如果 正单没有 就不处理这个退单
        if (null == orderInDd) {
            // TODO 记录错误
            return null;
        }

        // 订单表退单不存在
        if (ObjectUtil.isNull(refundOrderInDb)) {

            UnifiedOrder refundOrderNew = new UnifiedOrder();

            // 拷贝数据库里的订单信息
            copyFieldToRefundEntity(refundOrderNew, orderInDd);
            writeFiledToRefundEntity(refundOrderNew, refundOrderPorcess);
            unifiedOrderMapper.insertSelective(refundOrderNew);

            refundOrderInDb = refundOrderNew;

        }
        // 订单表退单存在
        else {

            // 拷贝数据库里的订单信息
            copyFieldToRefundEntity(refundOrderInDb, orderInDd);
            writeFiledToRefundEntity(refundOrderInDb, refundOrderPorcess);
            unifiedOrderMapper.updateByPrimaryKeySelective(refundOrderInDb);
        }

        reverseUpdateOrderFieldRefundOrderSn(orderInDd, refundOrderPorcess);

        return refundOrderInDb;

    }

    /**
     * 更新正单的 refundOrderSn 字段
     *
     * @param unifiedOrder
     * @param unifiedOrderReturn
     */
    private void reverseUpdateOrderFieldRefundOrderSn(UnifiedOrder unifiedOrder, UnifiedOrderReturn unifiedOrderReturn) {

        UnifiedOrder unifiedOrder4UpdateRefundOrderSn = new UnifiedOrder();
        unifiedOrder4UpdateRefundOrderSn.setId(unifiedOrder.getId());
        unifiedOrder4UpdateRefundOrderSn.setRefundOrderSn(unifiedOrderReturn.getReturnSn());

        unifiedOrderMapper.updateByPrimaryKeySelective(unifiedOrder4UpdateRefundOrderSn);

    }

    /**
     * 拷贝字段 TODO 因为过程可能有变,但也不是全部属性都会覆写更新的
     *
     * @param unifiedOrder
     * @param refundOrder
     */
    private void copyFieldToRefundEntity(UnifiedOrder refundOrder, UnifiedOrder unifiedOrder) {

        refundOrder.setServiceNo(unifiedOrder.getServiceNo());
        refundOrder.setServiceName(unifiedOrder.getServiceName());

        refundOrder.setSaleId(unifiedOrder.getSaleId());
        refundOrder.setSaleName(unifiedOrder.getSaleName());

        refundOrder.setProjectId(unifiedOrder.getProjectId());
        refundOrder.setProjectName(unifiedOrder.getProjectName());

        refundOrder.setPurchaseUserId(unifiedOrder.getPurchaseUserId());
        refundOrder.setPurchaseUserName(unifiedOrder.getPurchaseUserName());
        refundOrder.setPurchasePhone(unifiedOrder.getPurchasePhone());

        refundOrder.setPurchaseDepartmentName(unifiedOrder.getPurchaseDepartmentName());

        refundOrder.setPurchaseVirtId(unifiedOrder.getPurchaseVirtId());
        refundOrder.setPurchaseVirtName(unifiedOrder.getPurchaseVirtName());


        // TODO 写死
        refundOrder.setSettlementType(2);
        // TODO 写死
        refundOrder.setSourceChannel(1);
        // TODO 写死
        refundOrder.setAppraiseState(2);

    }

    /**
     * 覆写字段
     *
     * @param refundOrder
     * @param unifiedOrderReturn
     */
    private void writeFiledToRefundEntity(UnifiedOrder refundOrder, UnifiedOrderReturn unifiedOrderReturn) {

        refundOrder.setOrderType(CommonOrderTypeEnum.退单.getKey());

        refundOrder.setProjectId(unifiedOrderReturn.getProjectId());
        refundOrder.setProjectName(unifiedOrderReturn.getProjectName());

        // 查证了一下 商城添加了字段 departmentName 所以这边添加一下覆写 mark by linjinyu at 20211210
        refundOrder.setPurchaseDepartmentName(unifiedOrderReturn.getPurchaseDepartmentName());

        // 这个逻辑就是这样,不要问,自己想想
        // 退单主体
        // 订单单号字段 存 退单单号
        // 退单单号字段 存 正单单号
        refundOrder.setOrderSn(unifiedOrderReturn.getReturnSn());
        refundOrder.setRefundOrderSn(unifiedOrderReturn.getOrderSn());

        refundOrder.setCompletState(unifiedOrderReturn.getCompletState());

        // 以下还是要验证一下
        refundOrder.setPayState(unifiedOrderReturn.getPayState());

        // 订单状态
        refundOrder.setOrderState(unifiedOrderReturn.getOrderState());
        refundOrder.setOrderStateName(unifiedOrderReturn.getOrderStateName());

        refundOrder.setCreateTime(unifiedOrderReturn.getCreateTime());
        refundOrder.setPayTime(unifiedOrderReturn.getPayTime());
        refundOrder.setSendTime(unifiedOrderReturn.getSendTime());
        refundOrder.setFinishTime(unifiedOrderReturn.getFinishTime());

        refundOrder.setUpdateTime(unifiedOrderReturn.getUpdateTime());

        /**************************************** mark by linjinyu at 2022-07-25 10:34:44 - start ****************************************/

        refundOrder.setExpress(unifiedOrderReturn.getExpress());
        refundOrder.setExpressCompany(unifiedOrderReturn.getExpressCompany());
        refundOrder.setExpressSn(unifiedOrderReturn.getExpressSn());

        /**************************************** mark by linjinyu at 2022-07-25 10:34:44 -   end ****************************************/


    }

    /**
     * 锁定
     *
     * @param orderSn
     */
    public void lockByOrderSn(String orderSn) {
        processBizGoodsLocking(orderSn, CommonAccountingLockingEnum.锁定);
    }

    /**
     * 解锁
     *
     * @param orderSn
     */
    public void unlockByOrderSn(String orderSn) {
        processBizGoodsLocking(orderSn, CommonAccountingLockingEnum.正常);
    }

    /**
     * 处理 结算时间 填充
     *
     * @param orderSn
     * @param refundOrderSn
     * @param refundOrderfinishTime
     */
    public void processBizOrderRecordAccountingTime(String orderSn, String refundOrderSn, Date refundOrderfinishTime, UnifiedOrderIssuesFlowingParam callback) {

        List<String> updateOrderSnList = new ArrayList<>();

        if (StrUtil.isNotBlank(orderSn)) {
            updateOrderSnList.add(orderSn);
        }

        if (StrUtil.isNotBlank(refundOrderSn)) {
            updateOrderSnList.add(refundOrderSn);
        }

        if (CollUtil.isNotEmpty(updateOrderSnList) && ObjectUtil.isNotEmpty(refundOrderfinishTime)) {

            UnifiedOrderExample unifiedOrderExample = new UnifiedOrderExample();
            unifiedOrderExample
                    .createCriteria()
                    .andOrderSnIn(updateOrderSnList);

            UnifiedOrder unifiedOrder4Update = new UnifiedOrder();
            unifiedOrder4Update.setAccountingTime(refundOrderfinishTime);
            unifiedOrderMapper.updateByExampleSelective(unifiedOrder4Update, unifiedOrderExample);
        } else {
            StringBuffer processReport = new StringBuffer(callback.getProcessReport());
            processReport.append("订单号或退单号或退单完成时间缺失,结算时间填充失败;");

            callback.setProcessReport(processReport.toString());
        }

    }

    private void processBizGoodsLocking(String orderSn, CommonAccountingLockingEnum lockingEnum) {

        if (ObjectUtil.isEmpty(orderSn)) {
            log.error("processBizGoodsLocking error | orderSn => {} | lockingEnum = {}", orderSn, lockingEnum.getDesc());
            return;
        }

        UnifiedOrderGoodsExample example = new UnifiedOrderGoodsExample();
        example.createCriteria()
                .andOrderSnEqualTo(orderSn);

        UnifiedOrderGoods unifiedOrderGoods4Lock = new UnifiedOrderGoods();
        unifiedOrderGoods4Lock.setGoodsLockingSupplier(lockingEnum.getKey());

        unifiedOrderGoodsMapper.updateByExampleSelective(unifiedOrderGoods4Lock, example);
    }

    public int processOrderBecomeInvalidIfExist(String refundOrderSn) {

        int ret = 0;

        int retUpdateOrder       = 0;
        int retUpdateOrderGoods  = 0;
        int retUpdateOrderCredit = 0;

        UnifiedOrderExample example = new UnifiedOrderExample();
        example.createCriteria()
                .andOrderSnEqualTo(refundOrderSn);

        List<UnifiedOrder> resultList = unifiedOrderMapper.selectByExample(example);

        if (CollUtil.isNotEmpty(resultList)) {

            UnifiedOrder sample4Update = new UnifiedOrder();
//            sample4Update.setAccountingStateCustomer(CommonAccountingStateEnum.已作废.getKey());
//            sample4Update.setAccountingStateSupplier(CommonAccountingStateEnum.已作废.getKey());
            retUpdateOrder = unifiedOrderMapper.updateByExampleSelective(sample4Update, example);

            retUpdateOrderGoods = processOrderGoodsBecomeInvalidIfExist(refundOrderSn);

            retUpdateOrderCredit = processOrderCreditBecomeInvalidIfExist(refundOrderSn);
        }

        if (retUpdateOrder > 1 && retUpdateOrderGoods > 1 && retUpdateOrderCredit > 1) {
            ret = 1;
        }

        return ret;

    }

    public int processOrderGoodsBecomeInvalidIfExist(String refundOrderSn) {

        int retUpdateOrderGoods = 0;

        UnifiedOrderGoodsExample example = new UnifiedOrderGoodsExample();
        example.createCriteria()
                .andOrderSnEqualTo(refundOrderSn);

        List<UnifiedOrderGoods> resultList = unifiedOrderGoodsMapper.selectByExample(example);

        if (CollUtil.isNotEmpty(resultList)) {

            UnifiedOrderGoods sample4Update = new UnifiedOrderGoods();
//            sample4Update.setAccountingStateCustomer(CommonAccountingStateEnum.已作废.getKey());
//            sample4Update.setAccountingStateSupplier(CommonAccountingStateEnum.已作废.getKey());

            retUpdateOrderGoods = unifiedOrderGoodsMapper.updateByExampleSelective(sample4Update, example);
        }

        return retUpdateOrderGoods;

    }

    public int processOrderCreditBecomeInvalidIfExist(String refundOrderSn) {

        int retUpdateOrderCredit = 0;

        UnifiedOrderCreditExample example = new UnifiedOrderCreditExample();
        example.createCriteria()
                .andOrderSnEqualTo(refundOrderSn);

        List<UnifiedOrderCredit> resultList = unifiedOrderCreditMapper.selectByExample(example);

        if (CollUtil.isNotEmpty(resultList)) {
            UnifiedOrderCredit sample4Update = new UnifiedOrderCredit();
//            sample4Update.setAccountingStateCustomer(CommonAccountingStateEnum.已作废.getKey());
//            sample4Update.setAccountingStateSupplier(CommonAccountingStateEnum.已作废.getKey());

            retUpdateOrderCredit = unifiedOrderCreditMapper.updateByExampleSelective(sample4Update, example);
        }

        return retUpdateOrderCredit;

    }

}
