package com.kcim.service.impl;

import com.kcim.common.constants.Constant;
import com.kcim.common.constants.NumberConstant;
import com.kcim.common.enums.ComputeTypeEnum;
import com.kcim.common.exception.CostException;
import com.kcim.common.util.UserContext;
import com.kcim.dao.model.ReportColumn;
import com.kcim.dao.repository.ReportColumnRepository;
import com.kcim.service.CenterService;
import com.kcim.service.ReportColumnService;
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.util.*;
import java.util.stream.Collectors;

/**
 * @program: CostAccount
 * @description: 报表设置实现类
 * @author: Wang.YS
 * @create: 2023-10-17 16:17
 **/
@Service("ReportColumnService")
@Slf4j
@AllArgsConstructor
public class ReportColumnServiceImpl implements ReportColumnService {
    ReportColumnRepository repository;
    CenterService centerService;

    /**
     * 基础设置-其他设置-报表项目设置-获取报表代码
     *
     * @return 报表列表
     */
    @Override
    public Object getReport() {
        DictDataVo dict = centerService.getDict(Constant.REPORT_TYPE);
        if(Objects.nonNull(dict)){
            List<DictDataVo> dataVoList = dict.getDataVoList();
            if(!CollectionUtils.isEmpty(dataVoList)){
                return dataVoList;
            }
        }
        return new ArrayList<>();
    }

    /**
     * 基础设置-其他设置-报表项目设置-获取报表列
     *
     * @param reportCode 报表代码
     * @return 报表列数据
     */
    @Override
    public Object getReportColumn(String reportCode) {
        List<ReportColumn> columns = repository.getByReportCode(reportCode);
        if(!CollectionUtils.isEmpty(columns)){
            matchDict(columns);
            //取出合计项
            List<ReportColumn> parent = columns.stream().filter(f -> f.getParentColumnCode().equals(NumberConstant.ZERO_L)).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(parent)){
                columns.removeAll(parent);
            }
            //按父类代码分组
            if(!CollectionUtils.isEmpty(columns)){
                Map<Long, List<ReportColumn>> collect = columns.stream().collect(Collectors.groupingBy(ReportColumn::getParentColumnCode));
                if(!CollectionUtils.isEmpty(parent)){
                    for (ReportColumn reportColumn : parent) {
                        Long columnCode = reportColumn.getColumnCode();
                        List<ReportColumn> reportColumns = collect.get(columnCode);
                        if(!CollectionUtils.isEmpty(reportColumns)){
                            reportColumn.setChildColumns(reportColumns);
                        }
                    }
                    return parent;
                }
            }else {
                if(!CollectionUtils.isEmpty(parent)){
                    return parent;
                }
            }


        }
        return new ArrayList<>();
    }

    private void matchDict(List<ReportColumn> columns) {
        //获取字典数据
        DictDataVo reportItemType = centerService.getDict(Constant.REPORT_ITEM_TYPE);
        Map<String,String> reportItemTypeMap = reportItemType.getDataVoList().stream().collect(Collectors.toMap(DictDataVo::getCode, DictDataVo::getName, (a, b) -> b));
        DictDataVo reportRedirectPath = centerService.getDict(Constant.REPORT_REDIRECT_PATH);
        Map<String,String> reportRedirectPathMap = reportRedirectPath.getDataVoList().stream().collect(Collectors.toMap(DictDataVo::getCode, DictDataVo::getName, (a, b) -> b));
        DictDataVo reportRedirectParam = centerService.getDict(Constant.REPORT_REDIRECT_PARAM);
        Map<String,String> reportRedirectParamMap = reportRedirectParam.getDataVoList().stream().collect(Collectors.toMap(DictDataVo::getCode, DictDataVo::getName, (a, b) -> b));
        for (ReportColumn column : columns) {
            Integer computeType = column.getComputeType();
            if(computeType.equals(ComputeTypeEnum.ITEM_TYPE.getCode())){
                String computeSource = column.getComputeSource();
                column.setComputeSourceName(reportItemTypeMap.get(computeSource));
                column.setComputeTypeName(ComputeTypeEnum.ITEM_TYPE.getName());
            } else if (computeType.equals(ComputeTypeEnum.CALCULATION_FORMULA.getCode())) {
                column.setComputeTypeName(ComputeTypeEnum.CALCULATION_FORMULA.getName());
                column.setComputeSourceName(column.getComputeSource());

            } else if (computeType.equals(ComputeTypeEnum.SUM.getCode())) {
                column.setComputeTypeName(ComputeTypeEnum.SUM.getName());
            }
            String redirect = column.getRedirect();
            if(!StringUtils.isEmpty(redirect)){
                String s = reportRedirectPathMap.get(redirect);
                column.setRedirectName(s);
            }
            String redirectParameter = column.getRedirectParameter();
            //判断是否有多个
            if(!StringUtils.isEmpty(redirectParameter)) {
                if (redirectParameter.contains("|")) {
                    String[] split = StringUtils.split(redirectParameter, "|");
                    StringBuilder sb = new StringBuilder();
                    if (split != null) {
                        for (String s : split) {
                            sb.append(reportRedirectParamMap.get(s)).append("|");
                        }
                    }
                    column.setRedirectParameterName(sb.toString());
                } else {
                    //单个
                    column.setRedirectParameterName(reportRedirectParamMap.get(redirectParameter));
                }
            }
        }
    }

    /**
     * 基础设置-其他设置-报表项目设置-添加报表列
     *
     * @param column 报表列数据
     */
    @Override
    public void addReportColumn(ReportColumn column) {
        Integer computeType = column.getComputeType();
        //判断是否是合计
        if(computeType.equals(NumberConstant.THREE)){
            //是合计 parentCode 默认为 0
            column.setParentColumnCode(NumberConstant.ZERO_L);
        }else {
            //其他类型判断父类代码是否存在 如果存在不处理  不存在 添加为最上层
            Long parentColumnCode = column.getParentColumnCode();
            if(StringUtils.isEmpty(parentColumnCode)){
                column.setParentColumnCode(NumberConstant.ZERO_L);
            }
        }
        column.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
        column.setCreateTime(new Date());
        column.setHospId(UserContext.getHospId());
        column.setColumnCode(getColumnCode(column.getReportCode()));
        repository.save(column);
    }

    private Long getColumnCode(String reportCode) {
        List<ReportColumn> columns = repository.getByReportCode(reportCode);
        if(!CollectionUtils.isEmpty(columns)){
            OptionalLong max = columns.stream().mapToLong(ReportColumn::getColumnCode).max();
            if(max.isPresent()){
                long asLong = max.getAsLong();
                return asLong + 1L;
            }else {
                return 1L;
            }
        }else {
            return 1L;
        }

    }

    @Override
    public void deleteReportColumn(Integer id) {
        ReportColumn reportColumn = repository.getById(id);
        if(Objects.nonNull(reportColumn)){
            Long parentColumnCode = reportColumn.getParentColumnCode();
            if(parentColumnCode.equals(NumberConstant.ZERO_L)){
                List<ReportColumn> byParentCode = repository.getByParentCode(reportColumn.getColumnCode());
                if(!CollectionUtils.isEmpty(byParentCode)){
                    for (ReportColumn column : byParentCode) {
                        column.setDeleteTime(new Date());
                        column.setDeleteUser(String.valueOf(UserContext.getCurrentUser().getId()));
                    }
                    repository.updateBatchById(byParentCode);
                    List<Integer> collect = byParentCode.stream().map(ReportColumn::getId).collect(Collectors.toList());
                    repository.removeByIds(collect);
                }
            }
            reportColumn.setDeleteTime(new Date());
            reportColumn.setDeleteUser(String.valueOf(UserContext.getCurrentUser().getId()));
            repository.updateById(reportColumn);
            repository.removeById(id);
        }else {
            throw new CostException("未找到需要删除的数据！请确认数据是否存在");
        }

    }

    @Override
    public void editReportColumn(ReportColumn column) {
        Integer id = column.getId();
        ReportColumn reportColumn = repository.getById(id);
        if(Objects.nonNull(reportColumn)){
            reportColumn.setColumnName(column.getColumnName());
            reportColumn.setComputeType(column.getComputeType());
            reportColumn.setComputeSource(column.getComputeSource());
            reportColumn.setSort(column.getSort());
            reportColumn.setDataType(column.getDataType());
            reportColumn.setRedirect(column.getRedirect());
            reportColumn.setRedirectParameter(column.getRedirectParameter());
            reportColumn.setUpdateUser(String.valueOf(UserContext.getCurrentUser().getId()));
            reportColumn.setUpdateTime(new Date());
            repository.updateById(reportColumn);
        }
    }
}
