package com.jwipc.finance.logic.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jwipc.exception.DaoException;
import com.jwipc.finance.convert.PaymentAdvanceRefundTransferApplyConvert;
import com.jwipc.finance.dto.PaymentAdvanceRefundTransferApplyBaseDTO;
import com.jwipc.finance.dto.PaymentAdvanceRefundTransferApplyListDTO;
import com.jwipc.finance.dto.PaymentAdvanceRefundTransferApplySaveDto;
import com.jwipc.finance.entity.PaymentAdvanceApply;
import com.jwipc.finance.entity.PaymentAdvanceRefundTransferApply;
import com.jwipc.finance.entity.PaymentAdvanceRefundTransferApplyDetail;
import com.jwipc.finance.logic.PaymentAdvanceApplyDetailLogic;
import com.jwipc.finance.logic.PaymentAdvanceRefundTransferApplyLogic;
import com.jwipc.finance.model.po.PaymentAdvanceRefundTransferApplyPO;
import com.jwipc.finance.model.query.PaymentAdvanceRefundTransferApplyHeadQuery;
import com.jwipc.finance.service.IPaymentAdvanceRefundTransferApplyDetailService;
import com.jwipc.finance.service.IPaymentAdvanceRefundTransferApplyService;
import com.jwipc.page.PageUtil;
import com.jwipc.page.PageView;
import com.jwipc.security.LoginUtil;
import com.jwipc.sys.client.SequenceClient;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author qzc
 * @date 2025/07/21
 */
@Service
@RequiredArgsConstructor
public class PaymentAdvanceRefundTransferApplyLogicImpl implements PaymentAdvanceRefundTransferApplyLogic {

    private final IPaymentAdvanceRefundTransferApplyService paymentAdvanceRefundTransferApplyService;
    private final PaymentAdvanceRefundTransferApplyConvert paymentAdvanceRefundTransferApplyConvert;
    private final IPaymentAdvanceRefundTransferApplyDetailService paymentAdvanceRefundTransferApplyDetailService;
    private final PaymentAdvanceApplyDetailLogic paymentAdvanceApplyDetailLogic;
    private final SequenceClient sequenceClient;
    @Override
    public PageView selectListByPage(PaymentAdvanceRefundTransferApplyHeadQuery query) {
        final Page<PaymentAdvanceApply> dbPage = PageUtil.toPage(query);
        List<PaymentAdvanceRefundTransferApply> paymentAdvanceRefundTransferApplies = paymentAdvanceRefundTransferApplyService.selectListByPage(dbPage, query);
        List<PaymentAdvanceRefundTransferApplyBaseDTO> dtoList = paymentAdvanceRefundTransferApplyConvert.POToDTOList(paymentAdvanceRefundTransferApplies);
        return PageUtil.getPV(dtoList, dbPage.getTotal());
    }

    @Override
    public PaymentAdvanceRefundTransferApplyListDTO selectById(Long id) {
        PaymentAdvanceRefundTransferApplyPO paymentAdvanceRefundTransferApplyPO = paymentAdvanceRefundTransferApplyService.selectById(id);
        return paymentAdvanceRefundTransferApplyConvert.poToDto(paymentAdvanceRefundTransferApplyPO);
    }

    /**
     * 保存预付款变更转单头和明细数据
     * @param data
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dataSave(PaymentAdvanceRefundTransferApplySaveDto data) throws Exception {
        List<PaymentAdvanceRefundTransferApplyDetail> refundTransferDetailList = Lists.newArrayList();
        for (PaymentAdvanceRefundTransferApplySaveDto.PaymentAdvanceRefundTransferApplyDetail paymentAdvanceRefundTransferApplyDetail : data.getItemList()) {
            paymentAdvanceRefundTransferApplyDetail.setPaymentChangeId(data.getId());
            paymentAdvanceRefundTransferApplyDetail.setPaymentChangeNumber(data.getPaymentChangeNo());
            paymentAdvanceRefundTransferApplyDetail.setDeleteFlag(0);
            String dataKey = paymentAdvanceRefundTransferApplyDetail.getAppNo()+"_"+paymentAdvanceRefundTransferApplyDetail.getAppItemNo();
            paymentAdvanceRefundTransferApplyDetail.setDataKey(dataKey);
            refundTransferDetailList.add(paymentAdvanceRefundTransferApplyConvert.detailDtoToPO(paymentAdvanceRefundTransferApplyDetail));
        }
       //判断是修改还是新增 1新增（暂存） 2修改
        if(1 == data.getSaveType()){
            //新增 BG+YYYY（年）+MM（月）+DD（日）+四位流水（0001）
            String refundTransferCode = sequenceClient.getCodeSequenceNo("payment_advance_refund_transfer_apply", 4);
            data.setPaymentChangeNo(refundTransferCode);
            PaymentAdvanceRefundTransferApply headData = paymentAdvanceRefundTransferApplyConvert.dtoToEntity(data.toAdvanceRefundTransferApply());
            headData.setCreateTime(LocalDateTime.now());
            headData.setCreateUserId(LoginUtil.getUserId());
            headData.setCreateUserName(LoginUtil.getAccount());
            headData.setCreateUserCode(LoginUtil.getName());
            headData.setStatus(0);//暂存状态 0 提交 1 财务驳回 2 财务确认是3
            headData.setDeleteFlag(0);
            String refundTransferMsg = paymentAdvanceRefundTransferApplyService.createRefundTransfer(headData, refundTransferDetailList);
            if (StringUtils.isNotEmpty(refundTransferMsg)) {
                throw new DaoException("数据保存成功。但" + refundTransferMsg);
            }
        }
        if (2 == data.getSaveType()) {
            //删除行时，需要找到删除的行信息进行修改判断
            PaymentAdvanceRefundTransferApply headData = paymentAdvanceRefundTransferApplyConvert.dtoToEntity(data.toAdvanceRefundTransferApply());
            headData.setUpdateTime(LocalDateTime.now());
            headData.setUpdateUserId(LoginUtil.getUserId());
            headData.setUpdateUserCode(LoginUtil.getAccount());
            headData.setUpdateUserName(LoginUtil.getName());
            headData.setDeleteFlag(0);
            if(0 == data.getDataType()){
            //查询出删除的数据
            LambdaQueryWrapper<PaymentAdvanceRefundTransferApplyDetail> wrapper = new LambdaQueryWrapper<PaymentAdvanceRefundTransferApplyDetail>()
                    .eq(PaymentAdvanceRefundTransferApplyDetail::getPaymentChangeId, headData.getId())
                    .eq(PaymentAdvanceRefundTransferApplyDetail::getDeleteFlag,0);
            List<PaymentAdvanceRefundTransferApplyDetail> list = paymentAdvanceRefundTransferApplyDetailService.list(wrapper);
            if(CollectionUtils.isNotEmpty(list)) {
                List<String> result = refundTransferDetailList.stream()//全部前台数据
                        .collect(Collectors.toMap(
                                detail -> detail.getAppNo() + "_" + detail.getAppItemNo(), // 拼接字符串作为键
                                detail -> detail.getAppNo() + "_" + detail.getAppItemNo(), // 值（这里直接使用拼接后的字符串，也可以根据需要调整）
                                (existing, replacement) -> replacement // 如果有重复，保留后出现的（即 replacement）
                        ))
                        .values() // 获取所有值
                        .stream()
                        .collect(Collectors.toList()); // 转换为 List
                Set<String> set2 = new HashSet<>(result);
                List<String> applyIdList = list.stream() //被删除的关联预付款明细单
                        .filter(detail -> {
                            String key = detail.getAppNo() + "_" + detail.getAppItemNo();
                            return !set2.contains(key); // 保留不在 list2 中的元素
                        })
                        .map(detail -> detail.getAppNo() + "_" + detail.getAppItemNo()) //
                        .collect(Collectors.toList());
                //修改中存在删除的情况
                if(CollectionUtils.isNotEmpty(applyIdList)){
                    for (String string : applyIdList) {
                        String appNo = string.split("_")[0];
                        String itemNo = string.split("_")[1];
                        paymentAdvanceApplyDetailLogic.updatePaymentAdvanceDetailDateType(appNo, itemNo, null);
                    }

//                    List<PaymentAdvanceRefundTransferApplyDetail> refundTransferApplyDetailByChangeId = paymentAdvanceRefundTransferApplyDetailService.findRefundTransferApplyDetailByChangeId(applyIdList);
//                    for (PaymentAdvanceRefundTransferApplyDetail detail : refundTransferApplyDetailByChangeId) {
//
//                    }
                }
            }
            }
            //进行删除后新增动作因该在修改反写标识之后操作
            String refundTransferMsg = paymentAdvanceRefundTransferApplyService.editRefundTransfer(headData, refundTransferDetailList);
            if (StringUtils.isNotEmpty(refundTransferMsg)) {
                throw new DaoException("数据保存成功。但" + refundTransferMsg);
            }
        }
        //需要在这里进行预付款单标识反写
        //反写转单的预付款明细
        for (PaymentAdvanceRefundTransferApplyDetail detail : refundTransferDetailList) {
            String appNo = detail.getAppNo();
            String itemNo=detail.getAppItemNo();
            if(0 == data.getDataType()){
                paymentAdvanceApplyDetailLogic.updatePaymentAdvanceDetailDateType(appNo,itemNo,0);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delRefundTransferApply(List<Long> applyIdList) {
        List<PaymentAdvanceRefundTransferApply> dataStatusByIdList = paymentAdvanceRefundTransferApplyService.findDataStatusByIdList(applyIdList);
        //需要判断哪些状态不可删除
        List<PaymentAdvanceRefundTransferApply> applyList = Lists.newArrayList();

        for (Long applyId : applyIdList) {
            PaymentAdvanceRefundTransferApply apply = new PaymentAdvanceRefundTransferApply();
            apply.setId(applyId);
            apply.setDeleteFlag(1);
            apply.setUpdateTime(LocalDateTime.now());
            apply.setUpdateUserId(LoginUtil.getUserId());
            apply.setUpdateUserCode(LoginUtil.getAccount());
            apply.setUpdateUserName(LoginUtil.getName());
            applyList.add(apply);
        }
        if (!paymentAdvanceRefundTransferApplyService.updateBatchById(applyList)) {
            throw new DaoException("删除预付款申请变更单失败, 请联系管理员");
        }
        //清除预付款订单明细关联转单标识
        PaymentAdvanceRefundTransferApply paymentAdvanceRefundTransferApply = dataStatusByIdList.get(0);
        if(0 == paymentAdvanceRefundTransferApply.getDataType()){
            List<PaymentAdvanceRefundTransferApplyDetail> refundTransferApplyDetailByChangeId = paymentAdvanceRefundTransferApplyDetailService.findRefundTransferApplyDetailByChangeId(applyIdList);
            if(CollectionUtils.isNotEmpty(refundTransferApplyDetailByChangeId)){
                for (PaymentAdvanceRefundTransferApplyDetail detail : refundTransferApplyDetailByChangeId) {
                    String appNo = detail.getAppNo();
                    String itemNo=detail.getAppItemNo();
                    paymentAdvanceApplyDetailLogic.updatePaymentAdvanceDetailDateType(appNo,itemNo,null);
                }
            }
        }
        // 删除对账付款申请明细数据
        paymentAdvanceRefundTransferApplyDetailService.delDetailByApplyId(applyIdList);


    }

    @Override
    public void submit(Long applyId) {
        PaymentAdvanceRefundTransferApply apply = new PaymentAdvanceRefundTransferApply();
        apply.setId(applyId);
        apply.setStatus(1);
        paymentAdvanceRefundTransferApplyService.updateById(apply);
    }

    @Override
    public void confirm(String paymentChangeNo, String approvalOpinion, Integer status) {
        LambdaUpdateWrapper<PaymentAdvanceRefundTransferApply> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(PaymentAdvanceRefundTransferApply::getStatus,status)
                .set(PaymentAdvanceRefundTransferApply::getApprovalOpinion,approvalOpinion)
                .eq(PaymentAdvanceRefundTransferApply::getPaymentChangeNo,paymentChangeNo);
        paymentAdvanceRefundTransferApplyService.update(updateWrapper);
    }


//    public static void main(String[] args) {
//        //测试\
//        PaymentAdvanceRefundTransferApplyDetail a = new PaymentAdvanceRefundTransferApplyDetail();
//        a.setAppNo("a");
//        a.setAppItemNo("1");
//        PaymentAdvanceRefundTransferApplyDetail a1 = new PaymentAdvanceRefundTransferApplyDetail();
//        a1.setAppNo("b");
//        a1.setAppItemNo("2");
//        PaymentAdvanceRefundTransferApplyDetail a2 = new PaymentAdvanceRefundTransferApplyDetail();
//        a2.setAppNo("c");
//        a2.setAppItemNo("3");
//        PaymentAdvanceRefundTransferApplyDetail a3 = new PaymentAdvanceRefundTransferApplyDetail();
//        a3.setAppNo("d");
//        a3.setAppItemNo("4");
//        PaymentAdvanceRefundTransferApplyDetail a4 = new PaymentAdvanceRefundTransferApplyDetail();
//        a4.setAppNo("a");
//        a4.setAppItemNo("1");
//        List<PaymentAdvanceRefundTransferApplyDetail> list = new ArrayList<>();
//        list.add(a);
//        list.add(a1);
//        list.add(a2);
//
//        List<PaymentAdvanceRefundTransferApplyDetail> list1 = new ArrayList<>();
//        list1.add(a3);
//        list1.add(a4);
//
//        Map<String, PaymentAdvanceRefundTransferApplyDetail> distinctList = list.stream()
//                .collect(Collectors.toMap(
//                        item -> item.getAppNo() + item.getAppItemNo(), // 联合主键
//                        item -> item,                                   // 值
//                        (existing, replacement) -> existing            // 如果有重复，保留原记录
//                ));
//        Set<String> listKeys = distinctList.keySet();
//        List<PaymentAdvanceRefundTransferApplyDetail> collect = list1.stream()
//                .filter(item -> !listKeys.contains(item.getAppNo() + item.getAppItemNo()))
//                .collect(Collectors.toList());
//        for (PaymentAdvanceRefundTransferApplyDetail paymentAdvanceRefundTransferApplyDetail : collect) {
//            System.out.println(paymentAdvanceRefundTransferApplyDetail);
//        }
//    }
}
