package com.jeeplus.business.borrow.service;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.domain.Refund;
import com.jeeplus.business.borrow.domain.RefundHis;
import com.jeeplus.business.borrow.mapper.BorrowMapper;
import com.jeeplus.business.borrow.mapper.RefundHisMapper;
import com.jeeplus.business.borrow.mapper.RefundMapper;
import com.jeeplus.business.borrow.service.dto.BorrowDTO;
import com.jeeplus.business.borrow.service.dto.RefundDTO;
import com.jeeplus.business.reimbursement.domain.JyReimbursementDetailInfoBorrow;
import com.jeeplus.business.reimbursement.mapper.JyReimbursementInfoBorrowMapper;
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.util.*;

@Service
public class BorrowService {

    @Resource
    private BorrowMapper borrowMapper;

    @Resource
    private RefundMapper refundMapper;

    @Resource
    private JyReimbursementInfoBorrowMapper jyReimbursementInfoBorrowMapper;

    @Resource
    private RefundHisMapper refundHisMapper;

    /**
     * 列表管理
     * @param borrowDTO
     * @param page
     * @return
     */
    public IPage<BorrowDTO> findPageList(BorrowDTO borrowDTO, Page<BorrowDTO> page) throws Exception {
        QueryWrapper<BorrowDTO> queryWrapper = QueryWrapperGenerator.buildQueryCondition(borrowDTO, BorrowDTO.class);
        queryWrapper.eq("a.del_flag",0);
        //编号
        if (StringUtils.isNotBlank(borrowDTO.getNo())){
            queryWrapper.like("a.no",borrowDTO.getNo());
        }
        //原因
        if (StringUtils.isNotBlank(borrowDTO.getReason())){
            queryWrapper.like("a.reason",borrowDTO.getReason());
        }
        //借款人
        if (StringUtils.isNotBlank(borrowDTO.getCreateById())){
            queryWrapper.eq("a.create_by_id",borrowDTO.getCreateById());
        }
        //借款人部门
        if (StringUtils.isNotBlank(borrowDTO.getOfficeId())){
            queryWrapper.eq("so.id",borrowDTO.getOfficeId());
        }
        //借款时间
        if (borrowDTO.getCreateDates() != null && borrowDTO.getCreateDates().length > 0) {
            queryWrapper.between("a.create_time", borrowDTO.getCreateDates()[0], borrowDTO.getCreateDates()[1]);
        }
        //借款金额
        if (borrowDTO.getBorrowAmounts() != null) {
            if (StringUtils.isNotEmpty(borrowDTO.getBorrowAmounts()[0])) {
                queryWrapper.ge("a.money_lower", Double.parseDouble(borrowDTO.getBorrowAmounts()[0]));
            }
            if (borrowDTO.getBorrowAmounts().length>1 && StringUtils.isNotEmpty(borrowDTO.getBorrowAmounts()[1])) {
                queryWrapper.le("a.money_lower", Double.parseDouble(borrowDTO.getBorrowAmounts()[1]));
            }
        }
        IPage<BorrowDTO> pageList=borrowMapper.findPageList(queryWrapper,page);
        //获取借款报销表中的信息
        List<JyReimbursementDetailInfoBorrow> borrowList=jyReimbursementInfoBorrowMapper.getList();

        for (BorrowDTO item : pageList.getRecords()){
            if (CollectionUtils.isNotEmpty(borrowList)){
                for (JyReimbursementDetailInfoBorrow infoBorrow : borrowList) {
                    if (item.getId().equals(infoBorrow.getProjectId()) && infoBorrow.getStatus().equals("5")){
                        if (StringUtils.isNotBlank(item.getFinalMoney())){
                            Float moneyLower=Float.parseFloat(item.getFinalMoney());
                            Float number=Float.parseFloat(infoBorrow.getNumber());
                            Float money=moneyLower-number;
                            item.setFinalMoney(money.toString());
                            Float refund=Float.parseFloat(item.getRefundLower());
                            Float lower=refund+number;
                            item.setRefundLower(lower.toString());
                            //同时修改剩余借款金额
                            BorrowMoney borrowMoney = new BorrowMoney();
                            borrowMoney.setId(item.getId());
                            borrowMoney.setFinalMoney(money.toString());
                            borrowMapper.updateById(borrowMoney);

                        }else {
                            Float moneyLower=Float.parseFloat(item.getMoneyLower());
                            Float number=Float.parseFloat(infoBorrow.getNumber());
                            Float money=moneyLower-number;
                            item.setFinalMoney(money.toString());
                            item.setRefundLower(infoBorrow.getNumber());
                        }

                    }
                }
            }
        }

//            if (CollectionUtils.isNotEmpty(borrowList)){
//                for (JyReimbursementDetailInfoBorrow item : borrowList){
//                    pageList.getRecords().stream().forEach(data->{
//                        if (StringUtils.isNotBlank(item.getProjectId()) && StringUtils.isNotBlank(data.getId())){
//                            if (item.getProjectId().equals(data.getId())){
//                                Float moneyLower=Float.parseFloat(data.getFinalMoney());
//                                Float number=Float.parseFloat(item.getNumber());
//                                Float money=moneyLower-number;
//                                data.setFinalMoney(money.toString());
//                                data.setRefundLower(item.getNumber());
//                            }
//                        }
//                    });
//                    continue;
//                };
//            }


        return pageList;
    }

    /**
     * 根据id查询数据
     * @param id
     * @return
     */
    public BorrowDTO findById(String id) {
        BorrowDTO borrowDTO=borrowMapper.findById(id);

        // 查询附件信息
        List<WorkAttachmentInfo> files = borrowMapper.findFiles(id);
        if (CollectionUtils.isNotEmpty(files)) {
            for (WorkAttachmentInfo i : files) {
                i.setCreateBy(SpringUtil.getBean ( IUserApi.class ).getById(i.getBy()));
            }
        }
        borrowDTO.setFiles(files);
        return borrowDTO;
    }

    /**
     * 新增/修改
     * @param borrowDTO
     * @return
     */
    public String save(BorrowDTO borrowDTO) throws Exception {
        if (StringUtils.isNotBlank(borrowDTO.getId())){
            return update(borrowDTO);
        }
        return add(borrowDTO);
    }

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

        borrowMoney.setId(id);
        borrowMoney.setNo(borrowNo);
        borrowMoney.setCreateById(userDTO.getId());
        borrowMoney.setCreateTime(new Date());
        borrowMoney.setUpdateById(userDTO.getId());
        borrowMoney.setUpdateTime(new Date());
        borrowMoney.setMoneyLower(borrowDTO.getMoneyLower());//借款金额小写
        borrowMoney.setMoney(borrowDTO.getMoney());//借款金额大写
        borrowMoney.setFinalMoney(borrowDTO.getMoneyLower());//剩余借款金额
        borrowMoney.setStatus(borrowDTO.getStatus());
        borrowMoney.setReason(borrowDTO.getReason()); //借款用途
        borrowMapper.insert(borrowMoney);

        //在还款表中生成一条数据
        Refund refund = new Refund();
        refund.setBorrowId(id);
        refund.setStatus("0");
        refund.setFinalMoney(borrowDTO.getMoneyLower());
        refundMapper.insert(refund);

        // 保存附件列表信息
        if (CollectionUtils.isNotEmpty(borrowDTO.getFiles())) {
            saveFiles(borrowDTO.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("borrowMoney");
            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(BorrowDTO borrowDTO){
        //获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken());
        BorrowMoney borrowMoney = new BorrowMoney();
        BeanUtils.copyProperties(borrowDTO,borrowMoney);

        borrowMoney.setUpdateById(userDTO.getId());
        borrowMoney.setUpdateTime(new Date());
        borrowMoney.setFinalMoney(borrowDTO.getMoneyLower());
        borrowMapper.updateById(borrowMoney);

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

        return borrowDTO.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 = borrowMapper.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 = borrowMapper.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("borrowMoney");
                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 borrowDTO
     */
    public void updateStatusById(BorrowDTO borrowDTO) {
        borrowMapper.updateStatusById(borrowDTO.getId(),borrowDTO.getStatus());
    }

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

    /**
     * 添加或修改借款归还
     * @param refundDTO
     * @return
     */
    public String saveRefund(RefundDTO refundDTO) {
        //获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken());
        //修改借款归还中的数据
        Refund refund = new Refund();
        BeanUtils.copyProperties(refundDTO,refund);
        refund.setUpdateById(userDTO.getId());
        refund.setUpdateTime(new Date());
        refundMapper.updateById(refund);
        //查找出借款中的借款金额
        Refund id = refundMapper.selectById(refundDTO.getId());
        BorrowMoney borrowMoney = borrowMapper.selectById(id.getBorrowId());
        //同时修改借款中的剩余借款金额
        BorrowMoney borrow = new BorrowMoney();
        borrow.setFinalMoney(refundDTO.getFinalMoney());
        borrow.setId(borrowMoney.getId());
        borrowMapper.updateById(borrow);
        return refundDTO.getId();
    }

    /**
     * 根据id修改借款归还状态
     * @param refundDTO
     */
    public void updateRefundById(RefundDTO refundDTO) {
        borrowMapper.updateRefundById(refundDTO.getId(),refundDTO.getStatus());
        //如果审核同意,则往历史表中添加一条数据
        if (refundDTO.getStatus().equals("5")){
            //查询还款数据
            BorrowDTO dto = borrowMapper.findById(refundDTO.getId());
            String jsonString = JSON.toJSONString(dto);
            //根据id找到当前还款信息
            Refund refund = refundMapper.selectById(refundDTO.getId());
            RefundHis refundHis = new RefundHis();
            refundHis.setRefundMoney(refund.getRefundLower());
            refundHis.setCreateById(refund.getCreateById());
            refundHis.setRefundId(refund.getId());
            refundHis.setFinalMoney(refund.getFinalMoney());
            refundHis.setCreateTime(new Date());
            refundHis.setJsonData(jsonString);
            refundHisMapper.insert(refundHis);
        }
    }

    /**
     * 管理员修改
     * @param borrowDTO
     */
    public void adminEditForm(BorrowDTO borrowDTO) {
        //修改借款数据
        BorrowMoney borrowMoney = new BorrowMoney();
        borrowMoney.setFinalMoney(borrowDTO.getFinalMoney());
        borrowMoney.setMoneyLower(borrowDTO.getMoneyLower());
        borrowMoney.setMoney(borrowDTO.getMoney());
        borrowMoney.setId(borrowDTO.getId());
        borrowMapper.updateInfoById(borrowMoney);
        //修改还款数据
        Refund refundInfo = new Refund();
        refundInfo.setRefund(borrowDTO.getRefund());
        refundInfo.setRefundLower(borrowDTO.getRefundLower());
        refundInfo.setId(borrowDTO.getRefundId());
        borrowMapper.updateRefundInfoById(refundInfo);
    }

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

    /**
     * 根据还款id查询还款历史数据
     * @param id
     * @return
     */
    public List<Refund> findByBorId(String id) {
        List<Refund> refunds=borrowMapper.findByBorId(id);
        return refunds;
    }

    /**
     * 创建还款数据
     * @param id
     * @return
     */
    public String createReturnData(String id) {
        Refund refund = refundMapper.selectOne(new LambdaQueryWrapper<Refund>().eq(Refund::getBorrowId, id));
        if (ObjectUtils.isNotEmpty(refund)){
            return refund.getId();
        }else {
            Refund refund1 = new Refund();
            refund1.setBorrowId(id);
            refund1.setStatus("0");
            refundMapper.insert(refund1);
            return refund1.getId();
        }
    }

    /**
     * 根据还款id查询还款数据
     * @param id
     * @return
     */
    public BorrowDTO findByRefundId(String id) {
        Refund refund = refundMapper.selectOne(new LambdaQueryWrapper<Refund>().eq(Refund::getId, id));
        if (ObjectUtils.isNotEmpty(refund) && StringUtils.isNotBlank(refund.getBorrowId())){
            BorrowDTO byId = this.findById(refund.getBorrowId());
            return byId;
        }else {
            return new BorrowDTO();
        }
    }

    public RefundHis findHisById(String id) {
        RefundHis refundHis = borrowMapper.findHisById(id);
        return refundHis;
    }

    /**
     * 取消还款申请
     * @param id
     * @return
     */
    public Map<String, String> backSourceData(String id) {
        Map<String,String> map = new HashMap<>();
        map.put("result","error");
        //从历史表中根据还款id查找最近一次的还款数据
        RefundHis refundHis = borrowMapper.getByRefundId(id);
        //如果没有最近一次还款记录,则说明是第一次还款
        if (ObjectUtils.isEmpty(refundHis)){
            BorrowDTO borrowDTO = this.findByRefundId(id);
            if (ObjectUtils.isNotEmpty(borrowDTO)){
                //将还款信息还原成初始的信息
                Refund refund = refundMapper.selectOne(new LambdaQueryWrapper<Refund>().eq(Refund::getId, id));
                refund.setRefundLower("");
                refund.setRefund("");
                refund.setFinalMoney(borrowDTO.getMoneyLower());
                refund.setStatus("0");
                refundMapper.updateById(refund);
            }
            //同时修改借款表中的剩余借款金额
            BorrowMoney borrowMoney = new BorrowMoney();
            borrowMoney.setId(borrowDTO.getId());
            borrowMoney.setFinalMoney(borrowDTO.getMoneyLower());
            map.put("result","success");
            return map;
        }else {
            //解析json数据
            BorrowDTO borrowDTO = JSON.parseObject(refundHis.getJsonData(), BorrowDTO.class);
            //如果存在,则将还款信息还原成上一次的还款记录
            Refund refund = refundMapper.selectOne(new LambdaQueryWrapper<Refund>().eq(Refund::getId, id));
            refund.setFinalMoney(refundHis.getFinalMoney());
            refund.setRefundLower(refundHis.getRefundMoney());
            refund.setStatus(borrowDTO.getRefundStatus());
            refund.setProcInsId(borrowDTO.getProcInsIdRefund());
            refund.setProcessDefinitionId(borrowDTO.getProcDefIdRefund());
            refundMapper.updateById(refund);
            //同时修改借款表中的剩余借款金额
            BorrowMoney borrowMoney = new BorrowMoney();
            borrowMoney.setId(refund.getBorrowId());
            borrowMoney.setFinalMoney(refundHis.getFinalMoney());
            borrowMapper.updateById(borrowMoney);
            map.put("result","success");
        }
        return map;
    }

    /**
     * 根据id查找所有还款金额
     * @param id
     * @return
     */
    public BorrowDTO getByReId(String id) {
        BorrowDTO borrowDTO=borrowMapper.getByReId(id);
        // 查询附件信息
        List<WorkAttachmentInfo> files = borrowMapper.findFiles(id);
        if (CollectionUtils.isNotEmpty(files)) {
            for (WorkAttachmentInfo i : files) {
                i.setCreateBy(SpringUtil.getBean ( IUserApi.class ).getById(i.getBy()));
            }
        }
        borrowDTO.setFiles(files);
        return borrowDTO;
    }
}
