package com.kcim.service.impl;

import com.kcim.common.constants.Constant;
import com.kcim.common.constants.NumberConstant;
import com.kcim.common.exception.CostException;
import com.kcim.common.util.BeanUtil;
import com.kcim.common.util.UserContext;
import com.kcim.dao.model.ShareParamCost;
import com.kcim.dao.model.ShareParamCostDetail;
import com.kcim.dao.repository.ShareParamCostDetailRepository;
import com.kcim.dao.repository.ShareParamCostRepository;
import com.kcim.service.CenterService;
import com.kcim.service.ItemCostShareService;
import com.kcim.vo.DictDataVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @program: CostAccount
 * @description: 项目成本分摊设置实现类
 * @author: Wang.YS
 * @create: 2024-01-22 15:44
 **/
@Service("ItemCostShareService")
@Slf4j
@AllArgsConstructor
public class ItemCostShareServiceImpl implements ItemCostShareService {
    ShareParamCostRepository repository;

    ShareParamCostDetailRepository detailRepository;

    CenterService centerService;

    @Override
    public Object getList(String filter) {
        List<ShareParamCost> list = repository.getList(filter);
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }

        // 查询报表 查询项目类型字典
        List<DictDataVo> medServiceItemType = getMedServiceItemType();
        List<DictDataVo> dataVoList = itemReportType();
        Map<String, String> reportTypeMap = dataVoList.stream().collect(Collectors.toMap(DictDataVo::getCode, DictDataVo::getName, (a, b) -> b));
        Map<String, String> medItemTypeMap = medServiceItemType.stream().collect(Collectors.toMap(DictDataVo::getCode, DictDataVo::getName, (a, b) -> b));


        //查询明细表
        List<String> collect = list.stream().map(ShareParamCost::getColumnCode).collect(Collectors.toList());
        List<ShareParamCostDetail> byShareColumnCode = detailRepository.getByShareColumnCode(collect);
        if (!CollectionUtils.isEmpty(byShareColumnCode)) {
            Map<String, List<ShareParamCostDetail>> collect1 = byShareColumnCode.stream().collect(Collectors.groupingBy(ShareParamCostDetail::getShareParamColumnCode));
            for (ShareParamCost shareParamCost : list) {
                List<ShareParamCostDetail> shareParamCostDetails = collect1.get(shareParamCost.getColumnCode());
                if (!CollectionUtils.isEmpty(shareParamCostDetails)) {
                    shareParamCost.setShareParamCostDetails(shareParamCostDetails);
                }
                if(!StringUtils.isEmpty(shareParamCost.getReportType())){
                    shareParamCost.setReportTypeName(reportTypeMap.get(shareParamCost.getReportType()));
                }
                if(!StringUtils.isEmpty(shareParamCost.getItemType())){
                    shareParamCost.setItemTypeName(medItemTypeMap.get(shareParamCost.getItemType()));
                }
            }
        }
        return list;
    }

    /**
     * @param request
     */
    @Override
    public void add(ShareParamCost request) {
        ShareParamCost paramCode = repository.getByParamCode(request.getColumnCode());
        if (Objects.nonNull(paramCode)) {
            throw new CostException("已存在相同成本列代码，请修改后再保存");
        }

        request.setHospId(UserContext.getHospId());
        request.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
        request.setCreateTime(new Date());
        repository.save(request);
    }

    /**
     * @param request
     */
    @Override
    public void update(ShareParamCost request) {
        Integer id = request.getId();
        if (Objects.isNull(id)) {
            throw new CostException("编辑时主键必填");
        }
        ShareParamCost paramCode = repository.getByParamCode(request.getColumnCode());
        ShareParamCost byId = repository.getById(id);
        if (Objects.isNull(paramCode) || paramCode.getId().equals(id)) {
            BeanUtil.convertObj(request, byId);
            byId.setUpdateTime(new Date());
            byId.setUpdateUser(String.valueOf(UserContext.getCurrentUser().getId()));
            repository.updateById(byId);
        } else {
            throw new CostException("已存在相同成本列代码，请修改后再保存");
        }


    }

    /**
     * @param id
     */
    @Override
    public void delete(Integer id) {
        repository.removeById(id);
    }

    /**
     * @param request
     */
    @Override
    public void addDetail(List<ShareParamCostDetail> request) {
        if (CollectionUtils.isEmpty(request)) {
            throw new CostException("未找到需要保存的数据");
        }
        checkPercent(request);

        //作废原有数据 重新保存
        String shareParamColumnCode = request.get(0).getShareParamColumnCode();
        detailRepository.removeByShareParamColumnCode(shareParamColumnCode);

        for (ShareParamCostDetail detail : request) {
            detail.setHospId(UserContext.getHospId());
            detail.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
            detail.setCreateTime(new Date());
        }
        detailRepository.saveBatch(request);
    }

    private void checkPercent(List<ShareParamCostDetail> request) {
        AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.00"));
        for (ShareParamCostDetail detail : request) {
            sum.updateAndGet(v -> v.add(detail.getPercent()));
        }
        BigDecimal decimal = sum.get();
        if (BigDecimal.ONE.compareTo(decimal) != NumberConstant.ZERO) {
            throw new CostException("占比加总为【" + decimal + "】,不等于1,请修改后再保存！");
        }

    }

    /**
     * @param request
     */
    @Override
    public void updateDetail(List<ShareParamCostDetail> request) {
        if (CollectionUtils.isEmpty(request)) {
            throw new CostException("未找到需要保存的数据");
        }
        //作废原有数据 重新保存
        String shareParamColumnCode = request.get(0).getShareParamColumnCode();
        detailRepository.removeByShareParamColumnCode(shareParamColumnCode);
        addDetail(request);
    }

    /**
     * @param id
     */
    @Override
    public void deleteDetail(Integer id) {

    }

    /**
     * @return
     */
    @Override
    public List<DictDataVo> itemReportType() {
        DictDataVo dict = centerService.getDict(Constant.PROFIT_REPORT_TYPE);
        if (Objects.isNull(dict)) {
            throw new CostException("未维护损益报表类型字典");
        }
        List<DictDataVo> dataVoList = dict.getDataVoList();
        if (CollectionUtils.isEmpty(dataVoList)) {
            throw new CostException("未维护损益报表类型字典");
        }

        return dataVoList;
    }

    /**
     * @return
     */
    @Override
    public List<DictDataVo> getMedServiceItemType() {
        DictDataVo dict = centerService.getCenterDict(Constant.MED_SERVICE_ITEM_TYPE);
        if (Objects.isNull(dict)) {
            throw new CostException("未维护医疗服务项目分类字典");
        }
        List<DictDataVo> dataVoList = dict.getDataVoList();
        if (CollectionUtils.isEmpty(dataVoList)) {
            throw new CostException("未维护医疗服务项目分类字典");
        }

        return dataVoList;
    }
}
