package com.jeeplus.business.payment.service;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeeplus.business.borrow.domain.BorrowMoney;
import com.jeeplus.business.borrow.service.dto.BorrowDTO;
import com.jeeplus.business.payment.domain.Payment;
import com.jeeplus.business.payment.mapper.PaymentMapper;
import com.jeeplus.business.payment.service.dto.PaymentDTO;
import com.jeeplus.business.project.domain.JyProject;
import com.jeeplus.business.project.mapper.JyProjectMapper;
import com.jeeplus.business.reimbursement.domain.JyReimbursementDetailInfoPayment;
import com.jeeplus.business.reimbursement.mapper.JyReimbursementInfoPaymentMapper;
import com.jeeplus.business.workClientInfo.domain.dto.JyWorkClientInfosDto;
import com.jeeplus.business.workClientInfo.mapper.JyWorkClientBankMapper;
import com.jeeplus.business.workClientInfo.mapper.JyWorkClientInfoMapper;
import com.jeeplus.business.workClientInfo.service.JyWorkClientService;
import com.jeeplus.common.TokenProvider;
import com.jeeplus.core.query.QueryWrapperGenerator;
import com.jeeplus.sys.domain.WorkAttachmentInfo;
import com.jeeplus.sys.feign.IUserApi;
import com.jeeplus.sys.feign.IWorkAttachmentApi;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.utils.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class PaymentService {

    @Resource
    private PaymentMapper paymentMapper;

    @Resource
    private JyProjectMapper jyProjectMapper;

    @Resource
    private JyWorkClientService jyWorkClientService;

    @Resource
    private JyReimbursementInfoPaymentMapper jyReimbursementInfoPaymentMapper;


    /*
    列表
     */
    public IPage<PaymentDTO> findPageList(PaymentDTO paymentDTO, Page<PaymentDTO> page) throws Exception {
        QueryWrapper<PaymentDTO> queryWrapper = QueryWrapperGenerator.buildQueryCondition(paymentDTO, PaymentDTO.class);
        queryWrapper.eq("a.del_flag",0);
        //编号
        if (StringUtils.isNotBlank(paymentDTO.getNo())){
            queryWrapper.like("a.no",paymentDTO.getNo());
        }
        //用途
        if (StringUtils.isNotBlank(paymentDTO.getReason())){
            queryWrapper.like("a.reason",paymentDTO.getReason());
        }
        //付款人
        if (StringUtils.isNotBlank(paymentDTO.getPaymentUser())){
            queryWrapper.eq("a.payment_user",paymentDTO.getPaymentUser());
        }
        //付款人部门
        if (StringUtils.isNotBlank(paymentDTO.getPaymentOffice())){
            queryWrapper.eq("so.id",paymentDTO.getPaymentOffice());
        }
        //付款时间
        if (paymentDTO.getCreateDates() != null && paymentDTO.getCreateDates().length > 0) {
            queryWrapper.between("a.payment_time", paymentDTO.getCreateDates()[0], paymentDTO.getCreateDates()[1]);
        }
        //付款金额
        if (paymentDTO.getPaymentAmounts() != null) {
            if (StringUtils.isNotEmpty(paymentDTO.getPaymentAmounts()[0])) {
                queryWrapper.ge("a.payment_lower", Double.parseDouble(paymentDTO.getPaymentAmounts()[0]));
            }
            if (paymentDTO.getPaymentAmounts().length>1 && StringUtils.isNotEmpty(paymentDTO.getPaymentAmounts()[1])) {
                queryWrapper.le("a.payment_lower", Double.parseDouble(paymentDTO.getPaymentAmounts()[1]));
            }
        }
        IPage<PaymentDTO> pageList=paymentMapper.findPageList(queryWrapper,page);
            pageList.getRecords().stream().forEach(data->{
                List<JyReimbursementDetailInfoPayment> list = jyReimbursementInfoPaymentMapper.findByProjectId(data.getId());
                Double total = 0.00;
                if (CollectionUtils.isNotEmpty(list)){
                    //将所有的报销金额汇总
                    for (JyReimbursementDetailInfoPayment reim : list) {
                        double parseDouble = Double.parseDouble(reim.getNumber());
                        total += parseDouble;
                    }
                }
                Double moneyLower=Double.parseDouble(data.getPaymentLower());
                Double money=moneyLower-total;
                data.setFinalMoney(money.toString());//剩余付款金额
                data.setRefund(total.toString());//冲抵金额
            });
        return pageList;


    }

    /**
     * 根据id查询数据
     * @param id
     * @return
     */
    public PaymentDTO findById(String id) {
        PaymentDTO paymentDTO=paymentMapper.findById(id);
        //查找项目信息
        if (StringUtils.isNotBlank(paymentDTO.getProjectId())){
            String[] split = paymentDTO.getProjectId().split(",");
            ArrayList<JyProject> projects = new ArrayList<>();
            for (String s : split) {
                JyProject project = jyProjectMapper.getById(s);
                projects.add(project);
            }
            paymentDTO.setProjectDTOList(projects);
        }
        // 查询附件信息
        List<WorkAttachmentInfo> files = paymentMapper.findFiles(id);
        if (CollectionUtils.isNotEmpty(files)) {
            for (WorkAttachmentInfo i : files) {
                i.setCreateBy(SpringUtil.getBean ( IUserApi.class ).getById(i.getBy()));
            }
        }
        paymentDTO.setFiles(files);

        return paymentDTO;
    }

    /*
    新增或修改
     */
    public String save(PaymentDTO paymentDTO) throws Exception {
        if (StringUtils.isNotBlank(paymentDTO.getId())){
            return update(paymentDTO);
        }
        return add(paymentDTO);
    }

    private String add(PaymentDTO paymentDTO) throws Exception {
        //获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken());
        //生成付款编号
        String No = SpringUtil.getBean ( IWorkAttachmentApi.class ).genSerialNum(userDTO.getCompanyDTO().getId(), PaymentDTO.BIZ_CODE, TokenProvider.getCurrentToken());
        //生成id
        String id = UUID.randomUUID().toString().replace("-", "");

        Payment payment = new Payment();
        //获取项目id
        String projectId="";
        if (ObjectUtils.isNotEmpty(paymentDTO.getProjectDTOList())){
            for (JyProject jyProject : paymentDTO.getProjectDTOList()) {
                projectId+=jyProject.getProjectId()+",";
            }
        }
        payment.setProjectId(projectId);
        payment.setNo(No);
        payment.setId(id);
        payment.setProceedType(paymentDTO.getProceedType());//收款类别
        payment.setProceedOfficeId(paymentDTO.getProceedOfficeId());//收款单位
        payment.setDutyNumber(paymentDTO.getDutyNumber()); //税号
        payment.setAmountPaid(paymentDTO.getAmountPaid());//累计已支付金额
        payment.setReason(paymentDTO.getReason());//用途
        payment.setPaymentLower(paymentDTO.getPaymentLower());//付款金额  小写
        payment.setPayment(paymentDTO.getPayment()); //大写
        payment.setPaymentType(paymentDTO.getPaymentType());//付款方式
        payment.setRemarks(paymentDTO.getRemarks()); //付款摘要
        payment.setPaymentUser(paymentDTO.getPaymentUser()); //付款人
        payment.setPaymentTime(paymentDTO.getPaymentTime());//付款时间
        payment.setOurBank(paymentDTO.getOurBank());//开户银行
        payment.setBankNumber(paymentDTO.getBankNumber());//银行账号
        payment.setStatus(paymentDTO.getStatus());
        payment.setRemarks(paymentDTO.getRemarks());//摘要
        paymentMapper.insert(payment);

        // 保存附件列表信息
        if (CollectionUtils.isNotEmpty(paymentDTO.getFiles())) {
            saveFiles(paymentDTO.getFiles(), userDTO, id);
        }
        return id;
    }

    /**
     * 保存附件信息
     * @param list 待保存的附件列表
     * @param userDTO 当前登录用户
     * @param id 关联id
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveFiles(List<WorkAttachmentInfo> list, UserDTO userDTO, String id) {
        int j = 1;
        for (WorkAttachmentInfo dto : list) {
            WorkAttachmentInfo i = new WorkAttachmentInfo();
            //包含了url、size、name
            i.setId(UUID.randomUUID().toString().replace("-", ""));
//            i.getCreateBy().setId(userDTO.getId());
            i.setCreateTime(new Date());
//            i.getUpdateBy().setId(userDTO.getId());
            i.setUpdateTime(new Date());
            i.setDelFlag(0);
            i.setUrl(dto.getUrl());
            //文件类型处理
            List<String> strings = Arrays.asList(dto.getName().split("\\."));
            if (org.flowable.editor.language.json.converter.util.CollectionUtils.isNotEmpty(strings)) {
                i.setType(strings.get(1));
            }
            i.setAttachmentId(id);
            i.setAttachmentName(dto.getName());
            i.setAttachmentFlag("paymentMoney");
            i.setFileSize(dto.getSize());
            i.setSort(j);
//            ossServiceMapper.insertWorkAttachment(i, userDTO);
            Map<String,String> map = new HashMap<>();
            String workAttachment = JSON.toJSONString((i));
            String userDTOInfo = JSON.toJSONString((userDTO));
            map.put("workAttachment",workAttachment);
            map.put("userDTO",userDTOInfo);
            SpringUtil.getBean ( IWorkAttachmentApi.class ).insertWorkAttachment(map);
            j++;
        }
    }

    private String update(PaymentDTO paymentDTO){
        Payment payment = new Payment();
        //获取项目id
        String projectId="";
        if (ObjectUtils.isNotEmpty(paymentDTO.getProjectDTOList())){
            for (JyProject jyProject : paymentDTO.getProjectDTOList()) {
                projectId+=jyProject.getProjectId()+",";
            }
        }
        payment.setProjectId(projectId);//项目
        payment.setProceedType(paymentDTO.getProceedType());//收款类别
        payment.setProceedOfficeId(paymentDTO.getProceedOfficeId());//收款单位
        payment.setDutyNumber(paymentDTO.getDutyNumber()); //税号
        payment.setAmountPaid(paymentDTO.getAmountPaid());//累计已支付金额
        payment.setReason(paymentDTO.getReason());//用途
        payment.setPaymentLower(paymentDTO.getPaymentLower());//付款金额  小写
        payment.setPayment(paymentDTO.getPayment()); //大写
        payment.setPaymentType(paymentDTO.getPaymentType());//付款方式
        payment.setRemarks(paymentDTO.getRemarks()); //付款摘要
        payment.setPaymentUser(paymentDTO.getPaymentUser()); //付款人
        payment.setPaymentTime(paymentDTO.getPaymentTime());//付款时间
        payment.setOurBank(paymentDTO.getOurBank());//开户银行
        payment.setBankNumber(paymentDTO.getBankNumber());//银行账号
        payment.setId(paymentDTO.getId());
        payment.setStatus(paymentDTO.getStatus());
        payment.setRemarks(paymentDTO.getRemarks());//摘要
        paymentMapper.updateById(payment);

        //获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken());

        // 修改附件信息列表
        if (CollectionUtils.isNotEmpty(paymentDTO.getFiles())) {
            updateFiles(paymentDTO.getFiles(), userDTO, paymentDTO.getId());
        }

        return paymentDTO.getId();
    }

    /**
     * 修改附件信息
     * @param list 待修改的附件列表
     * @param userDTO 当前登录用户
     * @param id 关联id
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateFiles(List<WorkAttachmentInfo> list, UserDTO userDTO, String id) {
        int j = 1;
        String names = new String();
        //表中存在，但是传过来不存在，说明已删除，表中数据也要删除
        for (WorkAttachmentInfo dto : list) {
            names = names + "," +dto.getUrl();
        }
        //查询保存的附件信息
        List<WorkAttachmentInfo> infoList = paymentMapper.findList(id);
        if (org.flowable.editor.language.json.converter.util.CollectionUtils.isNotEmpty(infoList)) {
            for (WorkAttachmentInfo i : infoList) {
                if (!names.contains(i.getUrl())) {
//                    ossServiceMapper.deleteById(i.getId());
                    SpringUtil.getBean ( IWorkAttachmentApi.class ).deleteById(i.getId());
                }
            }
        }
        //保存信息
        for (WorkAttachmentInfo dto : list) {
            //判断是否存在
            Integer isExit = paymentMapper.findIsExit(id, dto.getName());
            if (isExit == 0) {
                WorkAttachmentInfo i = new WorkAttachmentInfo();
                //包含了url、size、name
                i.setId(UUID.randomUUID().toString().replace("-", ""));
//                i.getCreateBy().setId(userDTO.getId());
                i.setCreateTime(new Date());
//                i.getUpdateBy().setId(userDTO.getId());
                i.setUpdateTime(new Date());
                i.setDelFlag(0);
                i.setUrl(dto.getUrl());
                //文件类型处理
                List<String> strings = Arrays.asList(dto.getName().split("\\."));
                if (org.flowable.editor.language.json.converter.util.CollectionUtils.isNotEmpty(strings)) {
                    i.setType(strings.get(1));
                }
                i.setAttachmentId(id);
                i.setAttachmentName(dto.getName());
                i.setAttachmentFlag("paymentMoney");
                i.setFileSize(dto.getSize());
                i.setSort(j);
                Map<String,String> map = new HashMap<>();
                String workAttachment = JSON.toJSONString((i));
                String userDTOInfo = JSON.toJSONString((userDTO));
                map.put("workAttachment",workAttachment);
                map.put("userDTO",userDTOInfo);
                SpringUtil.getBean ( IWorkAttachmentApi.class ).insertWorkAttachment(map);
//                ossServiceMapper.insertWorkAttachment(i, userDTO);
                j++;
            }
        }
    }


    /**
     * 根据id修改状态
     * @param paymentDTO
     */
    public void updateStatusById(PaymentDTO paymentDTO) {
        paymentMapper.updateStatusById(paymentDTO.getId(),paymentDTO.getStatus());
    }

    /**
     * 根据id进行删除
     * @param id
     * @return
     */
    public String deleteById(String id) {
        paymentMapper.deleteById(id);
        return "操作成功";
    }

    /**
     * 管理员修改
     * @param paymentDTO
     */
    public void adminEditForm(PaymentDTO paymentDTO) {
        Payment payment = new Payment();
        //获取项目id
        String projectId="";
        if (ObjectUtils.isNotEmpty(paymentDTO.getProjectDTOList())){
            for (JyProject jyProject : paymentDTO.getProjectDTOList()) {
                projectId+=jyProject.getProjectId()+",";
            }
        }
        payment.setProjectId(projectId);//项目
        payment.setProceedType(paymentDTO.getProceedType());//收款类别
        payment.setProceedOfficeId(paymentDTO.getProceedOfficeId());//收款单位
        payment.setDutyNumber(paymentDTO.getDutyNumber()); //税号
        payment.setAmountPaid(paymentDTO.getAmountPaid());//累计已支付金额
        payment.setReason(paymentDTO.getReason());//用途
        payment.setPaymentLower(paymentDTO.getPaymentLower());//付款金额  小写
        payment.setPayment(paymentDTO.getPayment()); //大写
        payment.setPaymentType(paymentDTO.getPaymentType());//付款方式
        payment.setRemarks(paymentDTO.getRemarks()); //付款摘要
        payment.setPaymentUser(paymentDTO.getPaymentUser()); //付款人
        payment.setPaymentTime(paymentDTO.getPaymentTime());//付款时间
        payment.setOurBank(paymentDTO.getOurBank());//开户银行
        payment.setBankNumber(paymentDTO.getBankNumber());//银行账号
        payment.setId(paymentDTO.getId());

        paymentMapper.updateInfoById(payment);
    }

    public IPage<Payment> listByUserId(Payment payment, Page<BorrowDTO> page) throws Exception {
        //获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken());
        QueryWrapper<Payment> queryWrapper = QueryWrapperGenerator.buildQueryCondition(payment, Payment.class);
        queryWrapper.eq("a.create_by_id",userDTO.getId());
        queryWrapper.eq("a.status","5");
        queryWrapper.orderByDesc("a.update_time");
        IPage<Payment> moneyList = paymentMapper.listByUserId(queryWrapper,page);
        return moneyList;
    }

    /**
     * 根据项目id查询付款信息
     * @param projectId
     * @return
     */
    public List<PaymentDTO> queryByProjectId(String projectId) {
        //根据项目id查找付款信息
        List<PaymentDTO> paymentDTOList = paymentMapper.queryByProjectId(projectId);
        //存放报销冲抵完成的集合
        ArrayList<String> successList = new ArrayList<>();

        if (CollectionUtils.isNotEmpty(paymentDTOList)){
            for (PaymentDTO paymentDTO : paymentDTOList) {
                //根据付款id查询报销信息
                List<JyReimbursementDetailInfoPayment> list = jyReimbursementInfoPaymentMapper.findByProjectId(paymentDTO.getId());
                Double total = 0.00;
                if (CollectionUtils.isNotEmpty(list)){
                    //将所有的报销金额汇总
                    for (JyReimbursementDetailInfoPayment reim : list) {
                        double parseDouble = Double.parseDouble(reim.getNumber());
                        total += parseDouble;
                    }
                }
                //付款金额
                double payment = Double.parseDouble(paymentDTO.getPaymentLower());

                //判断报销总金额与付款金额是否冲抵完成
                if (payment == total){
                    successList.add(paymentDTO.getId());
                }else {
                    Double money=payment-total;
                    paymentDTO.setFinalMoney(money.toString());
                    paymentDTO.setRefund(total.toString());
                }
            }
        }
        List<PaymentDTO> filteredPaymentDTOList = paymentDTOList.stream()
                .filter(item -> !successList.contains(item.getId())) // 检查ID是否在successList中
                .collect(Collectors.toList()); // 收集过滤后的元素到新列表中
        return filteredPaymentDTOList;
    }
}
