package com.artfess.cqlt.manager.impl;

import com.alibaba.fastjson.JSONObject;
import com.artfess.base.enums.DelStatusEnum;
import com.artfess.base.exception.BaseException;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.util.StringUtil;
import com.artfess.cqlt.dao.QfEnterpriseInfoDao;
import com.artfess.cqlt.dao.QfHrPersonDDao;
import com.artfess.cqlt.dao.QfHrPersonMDao;
import com.artfess.cqlt.dao.QfSubjectInternationalInfoDao;
import com.artfess.cqlt.manager.QfHrPersonDManager;
import com.artfess.cqlt.model.QfEnterpriseInfo;
import com.artfess.cqlt.model.QfHrPersonD;
import com.artfess.cqlt.model.QfHrPersonM;
import com.artfess.cqlt.model.QfSubjectInternationalInfo;
import com.artfess.cqlt.vo.DataInfoVo;
import com.artfess.cqlt.vo.ReportDataVo;
import com.artfess.i18n.util.I18nUtil;
import com.artfess.poi.util.CustomHeader;
import com.artfess.poi.util.HeaderNode;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.api.client.util.Lists;
import com.google.common.collect.Maps;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 人资--人员数据填报详情表 服务实现类
 *
 * @author min.wu
 * @company 阿特菲斯信息技术有限公司
 * @since 2023-02-27
 */
@Service
public class QfHrPersonDManagerImpl extends BaseManagerImpl<QfHrPersonDDao, QfHrPersonD> implements QfHrPersonDManager {

    @Resource
    private QfHrPersonMDao personMDao;

    @Resource
    private QfSubjectInternationalInfoDao subjectInternationalInfoDao;

    @Resource
    private QfEnterpriseInfoDao enterpriseInfoDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchSave(QfHrPersonM t) {
        Assert.hasText(t.getId(), I18nUtil.getMessage("QfOperationKpiM.reportId", LocaleContextHolder.getLocale()));
        QfHrPersonM personM = personMDao.selectById(t.getId());
        Assert.notNull(personM, I18nUtil.getMessage("filldata.notExist", LocaleContextHolder.getLocale()));
        Assert.isTrue(!"1".equals(personM.getStatus()),  I18nUtil.getMessage("data_operate", LocaleContextHolder.getLocale()));
        QueryWrapper<QfSubjectInternationalInfo> query = new QueryWrapper<>();
        query.eq("IS_DELE_", DelStatusEnum.N.getType());
        List<QfSubjectInternationalInfo> qfSubjectInternationalInfos = subjectInternationalInfoDao.selectList(query);
        Map<String, QfSubjectInternationalInfo> detailMap = qfSubjectInternationalInfos.stream().collect(Collectors.toMap(item -> item.getCode(), item -> item));
        QueryWrapper<QfEnterpriseInfo> enterpriseInfoQuery = new QueryWrapper<>();
        enterpriseInfoQuery.eq("IS_DELE_", DelStatusEnum.N.getType());
        List<QfEnterpriseInfo> enterpriseInfoList = enterpriseInfoDao.selectList(enterpriseInfoQuery);
        Map<String, QfEnterpriseInfo> enterpriseInfoMap = enterpriseInfoList.stream().collect(Collectors.toMap(item -> item.getCode(), item -> item));
        StringBuffer sb = new StringBuffer();
        t.getList().forEach(detail -> {
            detail.setMainId(t.getId());
            detail.setFillDate(personM.getFillDate());
            if (StringUtils.isEmpty(detail.getSubjectCode())) {
                throw new BaseException(I18nUtil.getMessage("fill.code", LocaleContextHolder.getLocale()));
            }
            if (!detailMap.containsKey(detail.getSubjectCode())) {
                sb.append(",");
                sb.append(detail.getSubjectCode());
            } else {
                QfSubjectInternationalInfo subjectInternationalInfo = detailMap.get(detail.getSubjectCode());
                detail.setSubjectNameEn(subjectInternationalInfo.getNameEn());
                detail.setSubjectUnit(subjectInternationalInfo.getUnit());
                detail.setSubjectName(subjectInternationalInfo.getName());
                if(!StringUtils.isEmpty(subjectInternationalInfo.getLevel())) {
                    detail.setSubjectLevel(Integer.parseInt(subjectInternationalInfo.getLevel()));
                }
            }

            //处理企业
            if (enterpriseInfoMap.containsKey(detail.getEnterpriseCode())) {
                QfEnterpriseInfo qfEnterpriseInfo = enterpriseInfoMap.get(detail.getEnterpriseCode());
                detail.setEnterpriseName(qfEnterpriseInfo.getName());
                detail.setEnterpriseNameEn(qfEnterpriseInfo.getNameEn());
            }
        });
        if (sb.length() > 0) {
            throw new BaseException(sb.substring(1) + I18nUtil.getMessage("code.notExist", LocaleContextHolder.getLocale()));
        }
        boolean b = this.saveOrUpdateBatch(t.getList());
        return b;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdate(QfHrPersonM t) {
        Assert.hasText(t.getId(), I18nUtil.getMessage("QfOperationKpiM.reportId", LocaleContextHolder.getLocale()));
        QfHrPersonM personM = personMDao.selectById(t.getId());
        List<QfHrPersonD> list = Lists.newArrayList();
        QueryWrapper<QfSubjectInternationalInfo> query = new QueryWrapper<>();
        query.eq("IS_DELE_", DelStatusEnum.N.getType());
        List<QfSubjectInternationalInfo> qfSubjectInternationalInfos = subjectInternationalInfoDao.selectList(query);
        Map<String, QfSubjectInternationalInfo> detailMap = qfSubjectInternationalInfos.stream().collect(Collectors.toMap(item -> item.getCode(), item -> item));
        QueryWrapper<QfEnterpriseInfo> enterpriseInfoQuery = new QueryWrapper<>();
        enterpriseInfoQuery.eq("IS_DELE_", DelStatusEnum.N.getType());
        List<QfEnterpriseInfo> enterpriseInfoList = enterpriseInfoDao.selectList(enterpriseInfoQuery);
        Map<String, QfEnterpriseInfo> enterpriseInfoMap = enterpriseInfoList.stream().collect(Collectors.toMap(item -> item.getCode(), item -> item));
        t.getList().forEach(detail -> {
            detail.setFillDate(personM.getFillDate());
            detail.setMainId(t.getId());
            QueryWrapper<QfHrPersonD> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("subject_code_", detail.getSubjectCode());
            queryWrapper.eq("main_id_", t.getId());
            queryWrapper.eq("enterprise_code_", detail.getEnterpriseCode());
            QfHrPersonD qfHrPersonD = this.baseMapper.selectOne(queryWrapper);
            if(null != qfHrPersonD) {
                qfHrPersonD.setActualYtd(detail.getFillData());
                list.add(qfHrPersonD);
            }else {
                QfSubjectInternationalInfo subjectInternationalInfo = detailMap.get(detail.getSubjectCode());
                detail.setSubjectNameEn(subjectInternationalInfo.getNameEn());
                detail.setSubjectUnit(subjectInternationalInfo.getUnit());
                detail.setSubjectName(subjectInternationalInfo.getName());
                if(!StringUtils.isEmpty(subjectInternationalInfo.getLevel())) {
                    detail.setSubjectLevel(Integer.parseInt(subjectInternationalInfo.getLevel()));
                }
                //处理企业
                if (enterpriseInfoMap.containsKey(detail.getEnterpriseCode())) {
                    QfEnterpriseInfo qfEnterpriseInfo = enterpriseInfoMap.get(detail.getEnterpriseCode());
                    detail.setEnterpriseName(qfEnterpriseInfo.getName());
                    detail.setEnterpriseNameEn(qfEnterpriseInfo.getNameEn());
                }
                list.add(detail);
            }
        });
        if(CollectionUtils.isEmpty(list)) {
            return false;
        }
        boolean b = this.saveOrUpdateBatch(list);
        return b;
    }

    @Override
    public void export(HttpServletRequest request, HttpServletResponse response, List<QfHrPersonD> list, String sheetName) throws IOException {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        String mainId = list.get(0).getMainId();

        List<String> enterpriseCodeHeader = this.baseMapper.getEnterpriseCodeHeader(mainId);

        List<String> subjectCodes = this.baseMapper.getSubjectCodes(mainId);
        Map<String, Integer> rowMap = Maps.newHashMap();
        AtomicReference<Integer> row = new AtomicReference<>(0);
        subjectCodes.forEach(subjectCode -> {
            row.getAndSet(row.get() + 1);
            rowMap.put(subjectCode, row.get());
        });
        Map<String, Integer> columMap = Maps.newHashMap();
        List<HeaderNode> headerNodeList = Lists.newArrayList();
        AtomicReference<Integer> column = new AtomicReference<>(1);
        enterpriseCodeHeader.forEach(code -> {
            column.getAndSet(column.get() + 1);
            HeaderNode headerNode = new HeaderNode();
            headerNode.setRow(0);
            headerNode.setColumn(column.get());
            headerNode.setHeaderName(code);
            headerNodeList.add(headerNode);
            columMap.put(code, headerNode.getColumn());
        });

        HeaderNode headerNode = new HeaderNode();
        headerNode.setRow(0);
        headerNode.setColumn(1);
        headerNode.setHeaderName("subjectCode");
        headerNodeList.add(headerNode);

        headerNode = new HeaderNode();
        headerNode.setRow(0);
        headerNode.setColumn(0);
        headerNode.setHeaderName("subjectName");
        headerNodeList.add(headerNode);

        list.forEach(person -> {
            HeaderNode node = new HeaderNode();
            node.setRow(rowMap.get(person.getSubjectCode()));
            node.setColumn(columMap.get(person.getEnterpriseCode()));
            node.setHeaderName(person.getFillData().toString());
            headerNodeList.add(node);

            node = new HeaderNode();
            node.setRow(rowMap.get(person.getSubjectCode()));
            node.setColumn(0);
            String spaceStr = StringUtil.addSpace(person.getSubjectLevel());
            node.setHeaderName(spaceStr + person.getSubjectName());
            headerNodeList.add(node);

            node = new HeaderNode();
            node.setRow(rowMap.get(person.getSubjectCode()));
            node.setColumn(1);
            node.setHeaderName(person.getSubjectCode());
            headerNodeList.add(node);
        });
        String date = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String fileName = String.format(sheetName + "-%s", date);
        CustomHeader.export(headerNodeList, response, fileName, sheetName);

    }

    @Override
    public List<JSONObject> detailQuery(List<QfHrPersonD> list) {
        if (CollectionUtils.isEmpty(list)) {
            return Lists.newArrayList();
        }
        String mainId = list.get(0).getMainId();

        List<String> enterpriseCodeHeader = this.baseMapper.getEnterpriseCodeHeader(mainId);

        List<String> subjectCodes = this.baseMapper.getSubjectCodes(mainId);

        List<JSONObject> detailList = Lists.newArrayList();

        JSONObject detail = new JSONObject(true);
        detail.put("subjectName","subjectName");
        detail.put("subjectCode","subjectCode");
        detail.put("subjectUnit","subjectUnit");
        detail.put("subjectLevel","subjectLevel");
        enterpriseCodeHeader.forEach(code -> {
            detail.put(code,code);

        });
        detailList.add(detail);
        for (String subjectCode : subjectCodes) {
            JSONObject data = new JSONObject(true);
            data.put("subjectCode", subjectCode);
            for (QfHrPersonD person : list) {
                if(person.getSubjectCode().equals(subjectCode)) {
                    data.put("subjectName", person.getSubjectName());
                    data.put("subjectUnit", person.getSubjectUnit());
                    data.put("subjectLevel", person.getSubjectLevel());
                    data.put(person.getEnterpriseCode(), person.getActualYtd());
                }
            }
            detailList.add(data);
        }

        return detailList;
    }

    @Override
    public List<ReportDataVo> getPersonDataList(List<String> subjectCodes, Integer fillYear, Integer endMonth) {
        if(CollectionUtils.isEmpty(subjectCodes)) {
            return Lists.newArrayList();
        }
        return this.baseMapper.getPersonDataList(subjectCodes, fillYear, endMonth);
    }

    @Override
    public List<QfHrPersonD> findBySubjectCode(DataInfoVo dataInfoVo, String subjectCode) {

        return this.baseMapper.findBySubjectCode(dataInfoVo, subjectCode);
    }

}
