package com.kcim.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kcim.common.exception.CostException;
import com.kcim.common.util.*;
import com.kcim.common.constants.NumberConstant;
import com.kcim.common.enums.DateStyleEnum;
import com.kcim.dao.mapper.CostCostingGroupMapper;
import com.kcim.dao.mapper.CostIncomeFileMapper;
import com.kcim.dao.mapper.CostIncomeGroupMapper;
import com.kcim.dao.mapper.ShareParamValueMapper;
import com.kcim.dao.model.*;
import com.kcim.dao.repository.ImportEmpCostRepository;
import com.kcim.dao.repository.ImportPatientInfoRepository;
import com.kcim.dao.repository.ImportPatientItemRepository;
import com.kcim.service.EmpCostImportService;
import com.kcim.service.PatientInfoImportService;
import com.kcim.service.PatientItemImportService;
import com.kcim.vo.CostIncomeFileVO;
import com.kcim.vo.IncomeErrorMessage;
import com.kcim.vo.SessionUserVO;
import com.kcim.service.CostIncomeFileService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


@Service("costIncomeFileService")
public class CostIncomeFileServiceImpl extends ServiceImpl<CostIncomeFileMapper, CostIncomeFile> implements CostIncomeFileService {

    private static final String INCOME_FILETYPE = "收入数据";
    private static final String COST_FILETYPE = "成本数据";
    private static final String SHAREPARAM_FILETYPE = "成本分摊参数数据";

    private static final String EMP_COST_TYPE = "人事成本数据";

    private static final String PATIENT_INFO = "患者信息";

    private static final String PATIENT_ITEM = "患者项目";

    private final CostIncomeGroupMapper costIncomeGroupMapper;
    private final CostCostingGroupMapper costCostingGroupMapper;
    private final ShareParamValueMapper paramValueMapper;
    private final ImportPatientInfoRepository importPatientInfoRepository;
    private final ImportPatientItemRepository importPatientItemRepository;
    private final ImportEmpCostRepository importEmpCostRepository;
    public CostIncomeFileServiceImpl(CostIncomeGroupMapper costIncomeGroupMapper, CostCostingGroupMapper costCostingGroupMapper,
                                     ShareParamValueMapper paramValueMapper, ImportPatientInfoRepository importPatientInfoRepository,
                                     ImportPatientItemRepository importPatientItemRepository, ImportEmpCostRepository importEmpCostRepository) {
        this.costIncomeGroupMapper = costIncomeGroupMapper;
        this.costCostingGroupMapper = costCostingGroupMapper;
        this.paramValueMapper = paramValueMapper;
        this.importPatientInfoRepository = importPatientInfoRepository;
        this.importPatientItemRepository = importPatientItemRepository;
        this.importEmpCostRepository = importEmpCostRepository;
    }

    /**
     * 保存文件上传记录
     *
     * @param list                   文件数据
     * @param file                   上传文件
     * @param hospId                 医院Id
     * @param incomeErrorMessageList 错误信息
     * @param uploadFile             文件路径
     * @return
     */
    @Override
    public CostIncomeFile saveCostIncomeFile(List<List<Object>> list, MultipartFile file, Long hospId, List<IncomeErrorMessage> incomeErrorMessageList, String uploadFile, Integer fileType, Integer year, Integer month) {
        CostIncomeFile costIncomeFile = new CostIncomeFile();

        String substring = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf(".")) + System.currentTimeMillis() + ".xsl";
        costIncomeFile.setFileName(substring);
        costIncomeFile.setFileUrl(uploadFile);
        costIncomeFile.setTotalAmount(list.size());
        if (!CollectionUtils.isEmpty(incomeErrorMessageList)) {
            costIncomeFile.setSuccessAmount(NumberConstant.ZERO);
            costIncomeFile.setErrorList(JacksonUtil.obj2Str(incomeErrorMessageList));
        } else {
            costIncomeFile.setSuccessAmount(list.size());
        }
        if (NumberConstant.ONE.equals(fileType)) {
            costIncomeFile.setFileType(SHAREPARAM_FILETYPE);
        } else if (NumberConstant.TWO.equals(fileType)) {
            costIncomeFile.setFileType(INCOME_FILETYPE);
        } else if (NumberConstant.THREE.equals(fileType)) {
            costIncomeFile.setFileType(COST_FILETYPE);
        } else {
            costIncomeFile.setFileType(file.getContentType());
        }
        SessionUserVO user = UserContext.getCurrentUser();
        costIncomeFile.setHospId(hospId);
        costIncomeFile.setUserName(user.getName());
        costIncomeFile.setUserId(user.getId());
        costIncomeFile.setDateYear(year);
        costIncomeFile.setDateMonth(month);
        costIncomeFile.setCreateTime(System.currentTimeMillis());
        this.save(costIncomeFile);
        return costIncomeFile;
    }
    @Override
    public CostIncomeFile saveFile(Integer fileSize, MultipartFile file, Long hospId, List<IncomeErrorMessage> incomeErrorMessageList, String uploadFile, Integer fileType, Integer year, Integer month) {
        CostIncomeFile costIncomeFile = new CostIncomeFile();

        String substring = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf(".")) + System.currentTimeMillis() + ".xsl";
        costIncomeFile.setFileName(substring);
        costIncomeFile.setFileUrl(uploadFile);
        costIncomeFile.setTotalAmount(fileSize);
        if (!CollectionUtils.isEmpty(incomeErrorMessageList)) {
            costIncomeFile.setSuccessAmount(NumberConstant.ZERO);
            costIncomeFile.setErrorList(JacksonUtil.obj2Str(incomeErrorMessageList));
        } else {
            costIncomeFile.setSuccessAmount(fileSize);
        }
        if (NumberConstant.ONE.equals(fileType)) {
            costIncomeFile.setFileType(SHAREPARAM_FILETYPE);
        } else if (NumberConstant.TWO.equals(fileType)) {
            costIncomeFile.setFileType(INCOME_FILETYPE);
        } else if (NumberConstant.THREE.equals(fileType)) {
            costIncomeFile.setFileType(COST_FILETYPE);
        } else if (NumberConstant.FOUR.equals(fileType)){
            costIncomeFile.setFileType(EMP_COST_TYPE);
        }else if (NumberConstant.FIVE.equals(fileType)){
            costIncomeFile.setFileType(PATIENT_INFO);
        }else if (NumberConstant.SIX.equals(fileType)){
            costIncomeFile.setFileType(PATIENT_ITEM);
        }else {
            costIncomeFile.setFileType(file.getContentType());
        }
        SessionUserVO user = UserContext.getCurrentUser();
        costIncomeFile.setHospId(hospId);
        costIncomeFile.setUserName(user.getName());
        costIncomeFile.setUserId(user.getId());
        costIncomeFile.setDateYear(year);
        costIncomeFile.setDateMonth(month);
        costIncomeFile.setCreateTime(System.currentTimeMillis());
        this.save(costIncomeFile);
        return costIncomeFile;
    }
    /**
     * 分页查询查询记录数据
     *
     * @param current  当前页
     * @param pageSize 页容量
     * @param fileName 文件名
     * @param dateTime 日期
     * @param hospId   当前院区
     * @param filter
     * @return
     */
    @Override
    public PageUtils queryList(Integer current, Integer pageSize, String fileName, String dateTime, Long hospId, String filter) {
        int year = 0;
        int month = 0;
        if (StrUtil.isNotBlank(dateTime)) {
            Date date = DateUtils.StringToDate(dateTime, DateStyleEnum.YYYY_MM);
            year = DateUtil.year(date);
            month = DateUtil.month(date) + 1;
        }
        Page<CostIncomeFile> costIncomeFilePage = new Page<>(current, pageSize);
        Page<CostIncomeFile> page = this.page(costIncomeFilePage, new QueryWrapper<CostIncomeFile>().lambda()
                .eq(CostIncomeFile::getHospId, hospId)
                .like(StrUtil.isNotBlank(fileName), CostIncomeFile::getFileName, fileName)
                .eq(StrUtil.isNotBlank(dateTime),CostIncomeFile::getDateYear,year)
                .eq(StrUtil.isNotBlank(dateTime),CostIncomeFile::getDateMonth,month)
                .orderByDesc(CostIncomeFile::getCreateTime));
        List<CostIncomeFile> records = page.getRecords();
        List<CostIncomeFileVO> costIncomeFileVOList = BeanUtil.convertList(records, CostIncomeFileVO.class);
        costIncomeFileVOList.forEach(i -> {
            String errorList = i.getErrorList();
            if (StrUtil.isNotBlank(errorList)) {
                i.setErrStatus(NumberConstant.ONE);
            }
            i.setDateTime(DateUtil.format(DateUtil.date(i.getCreateTime()), "yyyy-MM-dd"));
        });
        PageUtils pageUtils = new PageUtils(page);
        pageUtils.setList(costIncomeFileVOList);
        return pageUtils;
    }

    /**
     * 撤销导入
     *
     * @param id
     * @param hospId
     * @param computeDate
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteImport(Long id, Long hospId, String computeDate) {
        CostIncomeFile costIncomeFile = this.getById(id);
        if (Objects.isNull(costIncomeFile)) {
            throw new CostException(500, "文件记录不存在");
        }
        String fileType = costIncomeFile.getFileType();
        if (INCOME_FILETYPE.equals(fileType)) {
            // 根据文件的Id 和 医院Id获取数据
            List<CostIncomeGroup> costIncomeGroupList = costIncomeGroupMapper.selectList(new QueryWrapper<CostIncomeGroup>().lambda()
                    .eq(CostIncomeGroup::getHospId, hospId).eq(CostIncomeGroup::getFileId, id));
            if (CollectionUtils.isEmpty(costIncomeGroupList)) {
                throw new CostException(410, "数据已撤销");
            }
            List<Long> list = costIncomeGroupList.stream().map(CostIncomeGroup::getId).collect(Collectors.toList());
            costIncomeGroupMapper.deleteBatchIds(list);
        } else if (COST_FILETYPE.equals(fileType)) {
            // 根据文件的Id 和 医院Id获取数据
            List<CostCostingGroup> costIncomeGroupList = costCostingGroupMapper.selectList(new QueryWrapper<CostCostingGroup>().lambda()
                    .eq(CostCostingGroup::getHospId, hospId).eq(CostCostingGroup::getFileId, id));
            if (CollectionUtils.isEmpty(costIncomeGroupList)) {
                throw new CostException(410, "数据已撤销");
            }
            List<Long> list = costIncomeGroupList.stream().map(CostCostingGroup::getId).collect(Collectors.toList());
            costCostingGroupMapper.deleteBatchIds(list);
        }else if (SHAREPARAM_FILETYPE.equals(fileType)) {
            // 根据文件的Id 和 医院Id获取数据
            List<ShareParamValue> shareParamValues = paramValueMapper.selectList(
                    new LambdaQueryWrapper<ShareParamValue>()
                            .eq(ShareParamValue::getHospId, hospId)
                            .eq(ShareParamValue::getFileId, id));
            if (CollectionUtils.isEmpty(shareParamValues)) {
                throw new CostException(410, "数据已撤销");
            }
            List<Long> list = shareParamValues.stream().map(ShareParamValue::getId).collect(Collectors.toList());
            paramValueMapper.deleteBatchIds(list);
        } else if (EMP_COST_TYPE.equals(fileType)) {
            //人事成本数据
            importEmpCostRepository.removeEmpCostByFileId(computeDate,id);
        } else if (PATIENT_INFO.equals(fileType)) {
            //患者信息
            importPatientInfoRepository.removePatientInfoByFileId(computeDate,id);
        } else if (PATIENT_ITEM.equals(fileType)) {
            //患者项目
            importPatientItemRepository.removePatientItemByFileId(computeDate,id);
        }
        costIncomeFile.setRollbackStatus(NumberConstant.ONE);
        this.updateById(costIncomeFile);
    }

    /**
     * 错误详情
     *
     * @param id
     * @param hospId
     * @return
     */
    @Override
    public List<IncomeErrorMessage> getErrorList(Long id, Long hospId) {
        CostIncomeFile costIncomeFile = this.getById(id);
        if (Objects.isNull(costIncomeFile)) {
            throw new CostException(500, "文件记录不存在");
        }
        String errorList = costIncomeFile.getErrorList();
        if (StrUtil.isBlank(errorList)) {
            return null;
        }
//        List<IncomeErrorMessage> incomeErrorMessageList = JsonUtil.toList(errorList, IncomeErrorMessage.class);
        List<IncomeErrorMessage> incomeErrorMessageList = JacksonUtil.str2ObjList(errorList, List.class, IncomeErrorMessage.class);
        return incomeErrorMessageList;
    }

    /**
     * 文件记录删除
     *
     * @param idList 文件记录的Id集合
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void deleteByIds(List<Long> idList) {
        this.removeByIds(idList);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void reducingImport(Long id, Long hospId, String computeDate) {
        CostIncomeFile costIncomeFile = this.getById(id);
        if (Objects.isNull(costIncomeFile)) {
            throw new CostException(500, "文件记录不存在");
        }
        String fileType = costIncomeFile.getFileType();
        if (INCOME_FILETYPE.equals(fileType)) {
            // 根据文件的Id 和 医院Id获取数据 已撤销数据
            List<CostIncomeGroup> historyList = costIncomeGroupMapper.selectHistoryList(hospId,id);
            if(!CollectionUtils.isEmpty(historyList)){
                List<Long> list = historyList.stream().map(CostIncomeGroup::getId).collect(Collectors.toList());
                costIncomeGroupMapper.reducingHistory(id,hospId,list);
            }
        } else if (COST_FILETYPE.equals(fileType)) {
            // 根据文件的Id 和 医院Id获取数据
            List<CostCostingGroup> historyList = costCostingGroupMapper.selectHistoryList(hospId,id);
            if(!CollectionUtils.isEmpty(historyList)){
                List<Long> list = historyList.stream().map(CostCostingGroup::getId).collect(Collectors.toList());
                costCostingGroupMapper.reducingHistory(id,hospId,list);
            }

        }else if (SHAREPARAM_FILETYPE.equals(fileType)) {
            // 根据文件的Id 和 医院Id获取数据
            List<ShareParamValue> historyList = paramValueMapper.selectHistoryList(hospId,id);
            if(!CollectionUtils.isEmpty(historyList)){
                List<Long> list = historyList.stream().map(ShareParamValue::getId).collect(Collectors.toList());
                paramValueMapper.reducingHistory(id,hospId,list);
            }
        } else if (EMP_COST_TYPE.equals(fileType)) {
            //人事成本数据
            importEmpCostRepository.reducingEmpCostByFileId(computeDate,id);
        } else if (PATIENT_INFO.equals(fileType)) {
            //患者信息
            importPatientInfoRepository.reducingPatientInfoByFileId(computeDate,id);
        } else if (PATIENT_ITEM.equals(fileType)) {
            //患者项目
            importPatientItemRepository.reducingPatientItemByFileId(computeDate,id);
        }
        costIncomeFile.setRollbackStatus(NumberConstant.ZERO);
        this.updateById(costIncomeFile);
    }

    @Override
    public void removeByComputeAndFileType(String computeDate, Integer type) {
        //
        /**
         *   private static final String INCOME_FILETYPE = "收入数据";
         *     private static final String COST_FILETYPE = "成本数据";
         *     private static final String SHAREPARAM_FILETYPE = "成本分摊参数数据";
         *
         *     private static final String EMP_COST_TYPE = "人事成本数据";
         *
         *     private static final String PATIENT_INFO = "患者信息";
         *
         *     private static final String PATIENT_ITEM = "患者项目";
         */
        String fileType = null;
        if(type.equals(NumberConstant.ONE)){
            fileType = INCOME_FILETYPE;
        } else if (type.equals(NumberConstant.TWO)) {
            fileType = COST_FILETYPE;
        } else if (type.equals(NumberConstant.THREE)) {
            fileType = SHAREPARAM_FILETYPE;
        } else if (type.equals(NumberConstant.FOUR)) {
            fileType = EMP_COST_TYPE;
        } else if (type.equals(NumberConstant.FIVE)) {
            fileType = PATIENT_INFO;
        } else if (type.equals(NumberConstant.SIX)) {
            fileType = PATIENT_ITEM;
        }
        if(StringUtils.isEmpty(fileType)){
            throw new CostException("未知的文件类型");
        }
        this.removeFilter(computeDate,fileType);

    }

    private void removeFilter(String computeDate,String fileType) {
        UpdateWrapper<CostIncomeFile> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(CostIncomeFile::getDeleteTime,0)
                .eq(CostIncomeFile::getHospId,UserContext.getHospId())
                .eq(CostIncomeFile::getDateYear,ComputeDateUtils.getComputeYear(computeDate))
                .eq(CostIncomeFile::getDateMonth,ComputeDateUtils.getComputeMonth(computeDate))
                .eq(CostIncomeFile::getFileType,fileType)
                .set(CostIncomeFile::getRollbackStatus,NumberConstant.ONE);

        this.update(updateWrapper);




    }

}