package com.kcim.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.BeanUtil;
import com.kcim.common.util.PageUtils;
import com.kcim.common.util.UserContext;
import com.kcim.common.constants.NumberConstant;
import com.kcim.dao.mapper.CostNumberBedSetMapper;
import com.kcim.dao.model.CostNumberBedSet;
import com.kcim.dao.model.CostShareParam;
import com.kcim.dao.model.ReportForm;
import com.kcim.dao.model.dto.CostNumberBedSetEditDto;
import com.kcim.dao.model.dto.CostNumberBedSetSaveDto;
import com.kcim.vo.CheckShareParamStatusVO;
import com.kcim.vo.CostNumberBedSetVO;
import com.kcim.vo.ReportFormVO;
import com.kcim.service.CostNumberBedSetService;
import com.kcim.service.CostShareParamService;
import com.kcim.service.ReportFormService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

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


@Service("costNumberBedSetService")
public class CostNumberBedSetServiceImpl extends ServiceImpl<CostNumberBedSetMapper, CostNumberBedSet> implements CostNumberBedSetService {


    private final CostShareParamService costShareParamService;

    private final ReportFormService reportFormService;

    public CostNumberBedSetServiceImpl(CostShareParamService costShareParamService, ReportFormService reportFormService) {
        this.costShareParamService = costShareParamService;
        this.reportFormService = reportFormService;
    }

    /**
     * 分页查询诊次/床日设置
     *
     * @param current
     * @param pageSize
     * @param name
     * @param hospId
     * @return
     */
    @Override
    public PageUtils queryList(Integer current, Integer pageSize, String name, Long hospId) {
        Page<CostNumberBedSet> costNumberBedSetPage = new Page<>(current, pageSize);
        Page<CostNumberBedSet> pages = this.page(costNumberBedSetPage, new QueryWrapper<CostNumberBedSet>().lambda()
                .eq(CostNumberBedSet::getHospId, hospId)
                .like(StrUtil.isNotBlank(name),CostNumberBedSet::getIncomeFileName,name));
        List<CostNumberBedSet> records = pages.getRecords();
        List<CostNumberBedSetVO> costNumberBedSetVOList = BeanUtil.convertList(records, CostNumberBedSetVO.class);
        // 具体的名称根据Code  Id 进行获取
//        Map<String, ReportForm> reportFormMap = reportFormService.list(
//                new QueryWrapper<ReportForm>().lambda()
//                        .eq(ReportForm::getHospId, hospId)).stream()
//                .collect(Collectors.toMap(k->k.getNum().toString()+k.getReportType().toString(), synOe -> synOe));
//        costNumberBedSetVOList.forEach(i->{
//            setName(reportFormMap, i);
//        });
        PageUtils pageUtils = new PageUtils(pages);
        pageUtils.setList(costNumberBedSetVOList);
        return pageUtils;
    }

    /**
     * 设置成本分摊参数的名称  相关报表的名称
     * @param reportFormMap
     * @param i
     */
    private void setName( Map<Integer, ReportForm> reportFormMap, CostNumberBedSetVO i) {
        Integer incomeFieldNum = i.getIncomeFieldNum();
        Integer costCorresponding = i.getCostCorresponding();
        ReportForm reportForm = reportFormMap.get(incomeFieldNum);
        ReportForm reportForm1 = reportFormMap.get(costCorresponding);
        if (Objects.nonNull(reportForm)){
            Integer reportType = reportForm.getReportType();
            String reportName = reportForm.getReportName();
            reportName = getString(reportType, reportName);
            i.setIncomeFileName(reportName);
        }
        if (Objects.nonNull(reportForm1)){
            Integer reportType = reportForm1.getReportType();
            String costCorrespondingName = reportForm1.getReportName();
            costCorrespondingName = getString(reportType, costCorrespondingName);
            i.setCostCorrespondingName(costCorrespondingName);
        }
    }

    /**
     * 根据Id获取诊次/床日设置的数据
     *
     * @param id
     * @return
     */
    @Override
    public CostNumberBedSetVO getByNumberBedId(Long id) {
        Long hospId = UserContext.getHospId();
        CostNumberBedSet costNumberBedSet = this.getById(id);
        if (Objects.isNull(costNumberBedSet)){
            throw new CostException(500,"数据不存在");
        }
        Map<Integer, ReportForm> reportFormMap = reportFormService.list(new QueryWrapper<ReportForm>().lambda().eq(ReportForm::getHospId, hospId)).stream().collect(Collectors.toMap(ReportForm::getNum, synOe -> synOe));
        CostNumberBedSetVO costNumberBedSetVO = BeanUtil.convertObj(costNumberBedSet, CostNumberBedSetVO.class);
        setName(reportFormMap,costNumberBedSetVO);
        return costNumberBedSetVO;
    }
    private String getString(Integer reportType, String reportName) {
        switch (reportType) {
            case 0:
                reportName = "损益表" + reportName;
                break;
            case 1:
                reportName = "完全成本法表" + reportName;
                break;
            case 2:
                reportName = "变动成本表" + reportName;
                break;
            case 3:
                reportName = "全院损益表" + reportName;
                break;
            case 4:
                reportName = "全成本报表" + reportName;
                break;
            default:
                reportName = "";
        }
        return reportName;
    }
    /**
     * 添加诊次/床日设置的数据
     *  后期要考虑支持多选
     * @param costNumberBedSetSaveDto
     * @param hospId
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void addNumberBedSet(CostNumberBedSetSaveDto costNumberBedSetSaveDto, Long hospId) {
        String shareParamCodes = costNumberBedSetSaveDto.getShareParamCode();
        Integer incomeFieldNums = costNumberBedSetSaveDto.getIncomeFieldNum();
        CostNumberBedSet costNumberBedSet = this.getOne(new QueryWrapper<CostNumberBedSet>().lambda().eq(CostNumberBedSet::getHospId, hospId)
                .eq(CostNumberBedSet::getShareParamCode, shareParamCodes)
                .eq(CostNumberBedSet::getIncomeFieldNum, incomeFieldNums));
        if (Objects.nonNull(costNumberBedSet)){
            throw new CostException(500,"数据已经存在");
        }
        CostNumberBedSet costNumberBedSetRequest = BeanUtil.convertObj(costNumberBedSetSaveDto, CostNumberBedSet.class);
        costNumberBedSetRequest.setCreateTime(System.currentTimeMillis());
        costNumberBedSetRequest.setHospId(hospId);
        this.save(costNumberBedSetRequest);
    }

    /**
     * 修改诊次/床日的设置数据
     *
     * @param costNumberBedSetEditDto
     * @param hospId
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void updateNumberBedById(CostNumberBedSetEditDto costNumberBedSetEditDto, Long hospId) {
        Long id = costNumberBedSetEditDto.getId();
        CostNumberBedSet costNumberBedSet = this.getById(id);
        if (Objects.isNull(costNumberBedSet)){
            throw new CostException(500,"原始数据不存在");
        }
        String shareParamCodes = costNumberBedSetEditDto.getShareParamCode();
        Integer incomeFieldNums = costNumberBedSetEditDto.getIncomeFieldNum();
        this.removeById(id);
        CostNumberBedSet costNumberBedSetResponse = this.getOne(new QueryWrapper<CostNumberBedSet>().lambda().eq(CostNumberBedSet::getHospId, hospId)
                .eq(CostNumberBedSet::getShareParamCode, shareParamCodes)
                .eq(CostNumberBedSet::getIncomeFieldNum, incomeFieldNums));
        if (Objects.nonNull(costNumberBedSetResponse)){
            throw new CostException(500,"数据已经存在");
        }
        CostNumberBedSet costNumberBedSetRequest = BeanUtil.convertObj(costNumberBedSetEditDto, CostNumberBedSet.class);
        costNumberBedSetRequest.setHospId(hospId);
        costNumberBedSetRequest.setCreateTime(System.currentTimeMillis());
        costNumberBedSetRequest.setId(null);
        this.save(costNumberBedSetRequest);
    }

    /**
     * 获取当前诊次/床日设置里面关联的成本分摊参数
     *
     * @param id
     * @param hospId
     * @return
     */
    @Override
    public List<CheckShareParamStatusVO> checkStatus(Long id, Long hospId) {
        List<CostShareParam> costShareParamList = costShareParamService.list(new QueryWrapper<CostShareParam>().lambda()
                .eq(CostShareParam::getHospId, hospId));
        CostNumberBedSet costNumberBedSet = this.getById(id);
        String shareParamCode=null;
        if (Objects.nonNull(costNumberBedSet)){
            shareParamCode = costNumberBedSet.getShareParamCode();
        }
        List<CheckShareParamStatusVO> checkShareParamStatusVOList = BeanUtil.convertList(costShareParamList, CheckShareParamStatusVO.class);
        String finalShareParamCode = shareParamCode;
        checkShareParamStatusVOList.forEach(i->{
            String code = i.getShareParamCode();
            if (code.equals(finalShareParamCode)){
                i.setShareParamNumberBedSetStatus(NumberConstant.ONE);
            }
        });
        return checkShareParamStatusVOList;
    }

    /**
     * 获取报表  显示报表被选中的状态
     *
     * @param reportType 报表类型
     * @param hospId     医院Id
     * @param id
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public List<ReportFormVO> getReportNumberBedStatus(Integer reportType, Long hospId, Integer id) {
        List<ReportForm> list = reportFormService.list(new QueryWrapper<ReportForm>().lambda()
                .eq(ReportForm::getReportType, reportType)
                .eq(ReportForm::getHospId, hospId)
                .orderByAsc(ReportForm::getSort));

        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        List<ReportFormVO> reportFormVOS = list.stream().map(i -> {
            ReportFormVO reportFormVO = BeanUtil.convertObj(i, ReportFormVO.class);
            if (i.getCalcType() == 1) {
                reportFormVO.setShowAddRelation(1);
            } else if (i.getCalcType() == 2) {
                reportFormVO.setShowAddRelation(2);
            }
            return reportFormVO;
        }).collect(Collectors.toList());

        if (Objects.nonNull(id)){
            CostNumberBedSet costNumberBedSet = this.getById(id);
            if (Objects.nonNull(costNumberBedSet)){
                Integer incomeFieldNum = costNumberBedSet.getIncomeFieldNum();
                Integer costCorresponding = costNumberBedSet.getCostCorresponding();
                reportFormVOS.forEach(i->{
                    if (incomeFieldNum.equals(i.getNum()) && NumberConstant.ZERO.equals(reportType)){
                        i.setReportNumberSetStatus(NumberConstant.ONE);
                    }else if (costCorresponding.equals(i.getNum()) && NumberConstant.THREE.equals(reportType)){
                        i.setReportNumberSetStatus(NumberConstant.ONE);
                    }
                });
            }
        }


        List<ReportFormVO> roots = reportFormVOS.stream().filter(i -> i.getParentId() == 0L).collect(Collectors.toList());
        for (ReportFormVO root : roots) {
            List<ReportFormVO> children = root.getChildren();
            if (CollUtil.isEmpty(children)) {
                children = new ArrayList<>();
            }
            for (ReportFormVO reportFormVO : reportFormVOS) {
                if (reportFormVO.getParentId().equals(root.getId())) {
                    children.add(reportFormVO);
//                    this.setRelation(reportFormVO, user.getHospId());
                }
            }
            root.setChildren(children);
        }
        return roots;
    }

    /**
     * 删除诊次/床日成本设置
     *
     * @param idList idList
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void deleteByIds(List<Long> idList) {
        this.removeByIds(idList);
    }


}