package com.jeeplus.human.practice.reimburseRegister.service;

import cn.hutool.core.collection.CollectionUtil;
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.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeeplus.common.TokenProvider;
import com.jeeplus.core.query.QueryWrapperGenerator;
import com.jeeplus.flowable.feign.IFlowableApi;
import com.jeeplus.human.enrollment.enrollmentRegistration.utils.SnowFlake;
import com.jeeplus.human.practice.reimburseRegister.domain.ReimburseRegister;
import com.jeeplus.human.practice.reimburseRegister.domain.ReimburseRegisterDetail;
import com.jeeplus.human.practice.reimburseRegister.domain.ReimburseSubmitAccount;
import com.jeeplus.human.practice.reimburseRegister.domain.ReimburseSubmitAccountDetail;
import com.jeeplus.human.practice.reimburseRegister.mapper.ReimburseSubmitAccountDetailMapper;
import com.jeeplus.human.practice.reimburseRegister.mapper.ReimburseSubmitAccountMapper;
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 org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author 王强
 * @version 1.0
 * @date 2023-09-22 13:58
 */
@Service
@Transactional
public class ReimburseSubmitAccountService extends ServiceImpl<ReimburseSubmitAccountMapper, ReimburseSubmitAccount> {

    @Resource
    private ReimburseSubmitAccountMapper accountMapper;

    @Resource
    private IFlowableApi flowTaskService;

    @Resource
    private ReimburseSubmitAccountDetailMapper accountDetailMapper;

    /**
     * 实习报销信息
     * @param page
     * @param projectReportData
     * @return
     * @throws Exception
     */
    public IPage<ReimburseSubmitAccount> findList(Page<ReimburseSubmitAccount> page, ReimburseSubmitAccount projectReportData) throws Exception{
        QueryWrapper<ReimburseSubmitAccount> queryWrapper = QueryWrapperGenerator.buildQueryCondition (projectReportData,ReimburseSubmitAccount.class);
        queryWrapper.eq("a.del_flag","0");
        IPage<ReimburseSubmitAccount> list = accountMapper.findList(page, queryWrapper);
        list.getRecords().forEach(item -> {
            // 入库 修改申请
            if (com.jeeplus.utils.StringUtils.isNotBlank(item.getTaskId()) && com.jeeplus.utils.StringUtils.isNotBlank(item.getType())) {
                if ("2".equals(item.getType())) { // “审核中”的数据要获取数据审核人
                    item.setAuditUserIds(flowTaskService.getTaskAuditUsers(item.getTaskId()));  // 获取数据审核人
                }
            }
        });
        return list;

    }

    public void updateStatusById(ReimburseSubmitAccount dto) {
        accountMapper.updateStatusById(dto.getId(), dto.getType());
    }

    public ReimburseSubmitAccount findById(String id) {
        // 查询基础信息表
        ReimburseSubmitAccount info = accountMapper.getById(id);
        List<ReimburseSubmitAccountDetail> infos = accountDetailMapper.getInfoByInfoId(id);
        if (CollectionUtils.isNotEmpty(infos)){
            info.setAccountDetails(infos);
        }
        // 查询附件信息
        List<WorkAttachmentInfo> files = accountMapper.findFiles(id);
        if (CollectionUtils.isNotEmpty(files)) {
            for (WorkAttachmentInfo i : files) {
                i.setCreateBy(SpringUtil.getBean ( IUserApi.class ).getById(i.getBy()));
            }
            info.setFiles(files);
        }
        return info;
    }

    public String remove(String id) {
        // 删除基础信息表
        accountMapper.deleteById(id);
        return "操作成功";
    }

    public ReimburseSubmitAccount saveSubmitAccount(ReimburseSubmitAccount registration) throws Exception {
        if (StringUtils.isNotEmpty(registration.getId())){

            ReimburseSubmitAccount report = accountMapper.getById(registration.getId());
            if (report != null){
                return update(registration);
            }
        }
        return add(registration);
    }

    /**
     * 修改
     */
    @Transactional(rollbackFor = Exception.class)
    public ReimburseSubmitAccount update(ReimburseSubmitAccount reportData) throws Exception{
        //获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken ( ));

        ReimburseSubmitAccount report = new ReimburseSubmitAccount();
        BeanUtils.copyProperties(reportData, report);
        report.setUpdateById(userDTO.getId());
        report.setUpdateTime(new Date());

        if (StringUtils.isBlank(report.getNo())){
            //报销编号生成
            String serialNum = SpringUtil.getBean ( IWorkAttachmentApi.class ).genSerialNum(userDTO.getCompanyDTO().getId(), ReimburseSubmitAccount.BIZ_CODE, TokenProvider.getCurrentToken());
            report.setNo(serialNum);
        }

        //保存报销明细前先删除一下
        accountDetailMapper.deleteByReportId(report.getId());
        if (CollectionUtils.isNotEmpty(report.getAccountDetails())){
            List<ReimburseSubmitAccountDetail> amountInfos = report.getAccountDetails();
            for (ReimburseSubmitAccountDetail amountInfo : amountInfos) {
                // 生成id
                String amountId = SnowFlake.getId();
                amountInfo.setId(amountId);
                amountInfo.setCreateById(userDTO.getId());
                amountInfo.setCreateTime(new Date());
                amountInfo.setUpdateById(userDTO.getId());
                amountInfo.setUpdateTime(new Date());
                amountInfo.setDelFlag(0);
                // 保存基础表信息主键值
                amountInfo.setInfoId(report.getId());
                accountDetailMapper.insert(amountInfo);
            }
        }

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

        accountMapper.updateById(report);

        return report;
    }

    /**
     * 新增
     */
    @Transactional(rollbackFor = Exception.class)
    public ReimburseSubmitAccount add(ReimburseSubmitAccount reportData) throws Exception{

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

        ReimburseSubmitAccount report = new ReimburseSubmitAccount();
        BeanUtils.copyProperties(reportData, report);

        //报销编号生成
        String serialNum = SpringUtil.getBean ( IWorkAttachmentApi.class ).genSerialNum(userDTO.getCompanyDTO().getId(), ReimburseSubmitAccount.BIZ_CODE, TokenProvider.getCurrentToken());
        report.setNo(serialNum);
        String id = SnowFlake.getId();
        report.setId(id);

        //保存报销明细前先删除一下
        accountDetailMapper.deleteByReportId(report.getId());
        if (CollectionUtils.isNotEmpty(report.getAccountDetails())){
            List<ReimburseSubmitAccountDetail> amountInfos = report.getAccountDetails();
            for (ReimburseSubmitAccountDetail amountInfo : amountInfos) {
                // 生成id
                String amountId = SnowFlake.getId();
                amountInfo.setId(amountId);
                amountInfo.setCreateById(userDTO.getId());
                amountInfo.setCreateTime(new Date());
                amountInfo.setUpdateById(userDTO.getId());
                amountInfo.setUpdateTime(new Date());
                amountInfo.setDelFlag(0);
                // 保存基础表信息主键值
                amountInfo.setInfoId(report.getId());
                accountDetailMapper.insert(amountInfo);
            }
        }

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

        accountMapper.insert(report);
        return report;
    }

    /**
     * 保存附件信息
     * @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());
            //文件类型处理
            String fileName = dto.getName();
            List<String> strings = Arrays.asList(fileName.split("\\."));
            // 检查文件名是否有后缀
            if (CollectionUtil.isNotEmpty(strings) && strings.size() > 1) {
                // 获取最后一个部分作为文件类型
                i.setType(strings.get(strings.size() - 1));
            } else {
                // 如果没有后缀或文件名无效，设置一个默认类型或空
                i.setType("");
            }
            i.setAttachmentId(id);
            i.setAttachmentName(dto.getName());
            i.setAttachmentFlag("submitAccount");
            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++;
        }
    }

    /**
     * 修改附件信息
     * @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 = accountMapper.findFileList(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 = accountMapper.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());
                //文件类型处理
                String fileName = dto.getName();
                List<String> strings = Arrays.asList(fileName.split("\\."));
                // 检查文件名是否有后缀
                if (CollectionUtil.isNotEmpty(strings) && strings.size() > 1) {
                    // 获取最后一个部分作为文件类型
                    i.setType(strings.get(strings.size() - 1));
                } else {
                    // 如果没有后缀或文件名无效，设置一个默认类型或空
                    i.setType("");
                }
                i.setAttachmentId(id);
                i.setAttachmentName(dto.getName());
                i.setAttachmentFlag("submitAccount");
                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++;
            }
        }
    }
}
