package com.jwipc.finance.logic.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jwipc.finance.dto.InvoicedApplyDTO;
import com.jwipc.finance.entity.InvoicedApply;
import com.jwipc.finance.entity.InvoicedApplyDetail;
import com.jwipc.finance.entity.InvoicedApplyOpt;
import com.jwipc.finance.logic.InvoicedApplyOptLogic;
import com.jwipc.finance.service.IInvoicedApplyOptService;
import com.jwipc.security.dto.CurrentUserDTO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author shenyang.ou
 * @date 2024/3/5 14:36
 * @desc
 */
@Service
@RequiredArgsConstructor
public class InvoicedApplyOptLogicImpl implements InvoicedApplyOptLogic {
    private final IInvoicedApplyOptService invoicedApplyOptService;
    /**
     * 添加操作记录
     *
     * @param optType    操作类型 1:新增 2:编辑 3:删除
     * @param oldHead    原主表数据
     * @param currHead   变更后主表数据
     * @param oldDetail  变更前明细表数据
     * @param currDetail 变更后明细数据
     * @param user       当前操作用户
     */
    @Override
    public void addContentRecord(Integer optType, InvoicedApply oldHead, InvoicedApply currHead, List<InvoicedApplyDetail> oldDetail, List<InvoicedApplyDetail> currDetail, CurrentUserDTO user) {
        // 新增
        if(1 == optType || 3 == optType){
            if(null != currHead){
                InvoicedApplyOpt opt = new InvoicedApplyOpt();
                opt.setIaId(currHead.getId());
                opt.setIaNo(currHead.getInvoiceApplyNo());
                opt.setId(null);
                opt.setOptType(optType);
                opt.setCreateTime(LocalDateTime.now());
                opt.setCreateUserId(user.getUserId());
                opt.setCreateUserCode(user.getLoginName());
                opt.setCreateUserName(user.getName());
                invoicedApplyOptService.save(opt);
            }

            if(CollectionUtils.isNotEmpty(currDetail)){
                List<InvoicedApplyOpt> optList = Lists.newArrayList();
                for(InvoicedApplyDetail ud: currDetail){
                    InvoicedApplyOpt opt = new InvoicedApplyOpt();
                    opt.setIaId(ud.getIaId());
                    opt.setIaNo(ud.getIaNo());
                    opt.setIadId(ud.getId());
                    optList.add(opt);
                }
                for(InvoicedApplyOpt opt: optList){
                    opt.setId(null);
                    opt.setOptType(optType);
                    opt.setCreateTime(LocalDateTime.now());
                    opt.setCreateUserId(user.getUserId());
                    opt.setCreateUserCode(user.getLoginName());
                    opt.setCreateUserName(user.getName());
                }

                invoicedApplyOptService.saveBatch(optList);
            }
        }

        // 编辑
        if(2 == optType){
            if(null != oldHead && null != currHead){
                InvoicedApplyOpt opt = new InvoicedApplyOpt();
                opt.setId(null);
                opt.setIaId(currHead.getId());
                opt.setIaNo(currHead.getInvoiceApplyNo());
                opt.setUpdateContent(this.handleHeadUpdateContent(oldHead, currHead));
                opt.setOptType(optType);
                opt.setCreateTime(LocalDateTime.now());
                opt.setCreateUserId(user.getUserId());
                opt.setCreateUserCode(user.getLoginName());
                opt.setCreateUserName(user.getName());

                invoicedApplyOptService.save(opt);
            }

            if(CollectionUtils.isNotEmpty(currDetail)){
                Map<Long, String> map = Maps.newHashMap();
                for(InvoicedApplyDetail od: oldDetail){
                    Long odAsdId = od.getId();
                    for(InvoicedApplyDetail ud: currDetail){
                        if(odAsdId.equals(ud.getId())){
                            map.put(odAsdId, this.handleUpdateContent(od, ud));
                        }
                    }
                }

                List<InvoicedApplyOpt> optList = Lists.newArrayList();
                for (Map.Entry<Long, String> in : map.entrySet()) {
                    InvoicedApplyOpt opt = new InvoicedApplyOpt();
                    opt.setIadId(in.getKey());
                    opt.setUpdateContent(in.getValue());
                    optList.add(opt);
                }

                for(InvoicedApplyOpt opt: optList){
                    opt.setId(null);
                    opt.setOptType(optType);
                    opt.setCreateTime(LocalDateTime.now());
                    opt.setCreateUserId(user.getUserId());
                    opt.setCreateUserCode(user.getLoginName());
                    opt.setCreateUserName(user.getName());
                }

                invoicedApplyOptService.saveBatch(optList);
            }
        }
    }

    /**
     * 处理变更字段的记录
     *
     * @param od 更新前的数据
     * @param ud 更新后的数据
     * @return 结果
     */
    private String handleUpdateContent(InvoicedApplyDetail od, InvoicedApplyDetail ud){
        JSONArray rows = new JSONArray();

        // 到票含税金额
        if(0 != od.getTaxAmount().compareTo(ud.getTaxAmount())){
            JSONObject item = new JSONObject();
            item.put("updateField", "taxAmount");
            item.put("updateFieldName", "到票含税金额");
            item.put("oriValue", od.getTaxAmount());
            item.put("currValue", ud.getTaxAmount());
            rows.add(item);
        }

        // 到票含税单价
        if(0 != od.getTaxPrice().compareTo(ud.getTaxPrice())){
            JSONObject item = new JSONObject();
            item.put("updateField", "taxPrice");
            item.put("updateFieldName", "到票含税单价");
            item.put("oriValue", od.getTaxPrice());
            item.put("currValue", ud.getTaxPrice());
            rows.add(item);
        }

        // 到票税率
        if(od.getTaxValue().equals(ud.getTaxValue())){
            JSONObject item = new JSONObject();
            item.put("updateField", "taxValue");
            item.put("updateFieldName", "到票税率");
            item.put("oriValue", "(" + od.getTaxCode() + ")" + od.getTaxValue());
            item.put("currValue", "(" + ud.getTaxCode() + ")" + ud.getTaxValue());
            rows.add(item);
        }

        // 到票税额
        if(0 != od.getDiffTaxAmount().compareTo(ud.getDiffTaxAmount())){
            JSONObject item = new JSONObject();
            item.put("updateField", "DiffTaxAmount");
            item.put("updateFieldName", "到票税额");
            item.put("oriValue", od.getDiffTaxAmount());
            item.put("currValue", ud.getDiffTaxAmount());
            rows.add(item);
        }

        return rows.toJSONString();
    }


    /**
     * 处理表头变更字段记录
     *
     * @param oh 更新前的数据
     * @param uh 更新后的数据
     * @return 结果
     */
    private String handleHeadUpdateContent(InvoicedApply oh, InvoicedApply uh){
        JSONArray rows = new JSONArray();

        // 表头备注
        if(StringUtils.isNotEmpty(oh.getRemark()) && StringUtils.isNotEmpty(uh.getRemark())){
            if(oh.getRemark().equals(uh.getRemark())){
                JSONObject item = new JSONObject();
                item.put("updateField", "remark");
                item.put("updateFieldName", "备注");
                item.put("oriValue", oh.getRemark());
                item.put("currValue", uh.getRemark());
                rows.add(item);
            }
        }

        // 表头发票数量
        if(ObjectUtil.isNotNull(uh.getInvoiceNum())&&oh.getInvoiceNum().equals(uh.getInvoiceNum())){
            JSONObject item = new JSONObject();
            item.put("updateField", "invoiceNum");
            item.put("updateFieldName", "发票数量");
            item.put("oriValue", oh.getInvoiceNum());
            item.put("currValue", uh.getInvoiceNum());
            rows.add(item);
        }

        // 表头发票号
        if(ObjectUtil.isNotNull(uh.getInvoiceNum())&&oh.getInvoiceNo().equals(uh.getInvoiceNo())){
            JSONObject item = new JSONObject();
            item.put("updateField", "taxValue");
            item.put("updateFieldName", "发票号");
            item.put("oriValue", oh.getInvoiceNo());
            item.put("currValue", uh.getInvoiceNo());
            rows.add(item);
        }

        return rows.toJSONString();
    }
}
