package com.testor.module.aptitude.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.testor.biz.file.model.dto.FileDTO;
import com.testor.biz.rule.service.SysRuleService;
import com.testor.biz.sys.dict.data.controller.SysDictDataController;
import com.testor.biz.sys.dict.data.model.dto.SysDictDataComplexResponse;
import com.testor.biz.sys.dict.data.model.dto.SysDictDataListResponse;
import com.testor.biz.sys.dict.data.model.dto.SysDictDataRequest;
import com.testor.biz.sys.dict.data.model.dto.SysDictDataResponse;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.biz.sys.org.service.SysOrgService;
import com.testor.biz.sys.user.model.domain.SysUser;
import com.testor.biz.sys.user.service.SysUserService;
import com.testor.common.constant.DefaultRule;
import com.testor.module.aptitude.dao.TPersonAptitudeDao;
import com.testor.module.aptitude.model.domain.TPersonAptitude;
import com.testor.module.aptitude.model.domain.TPersonAptitudeDto;
import com.testor.module.aptitude.model.dto.AptitudeCount;
import com.testor.module.aptitude.model.dto.DataStatistics;
import com.testor.module.aptitude.model.dto.TPersonAptitudeDelParam;
import com.testor.module.aptitude.model.dto.TPersonAptitudeParam;
import com.testor.module.aptitude.service.TPersonAptitudeService;
import com.testor.module.duty.util.PoiExcelUtils;
import com.testor.module.notice.model.domain.TSysFile;
import com.testor.module.notice.service.TSysFileService;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.biz.models.BizGeneralResponse;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.exception.BusinessException;
import com.tongtech.tfw.backend.common.models.sys.UserInfo;
import com.tongtech.tfw.backend.core.helper.IdHelper;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import com.tongtech.tfw.backend.core.helper.TypeHelper;
import com.tongtech.tfw.backend.core.helper.bean.BeanHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import com.tongtech.tfw.backend.common.models.supers.SuperServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 人员资质管理Service业务层处理
 *
 * @author testor-framework
 * @date 2022-07-20 18:05:48
 */
@Service
public class TPersonAptitudeServiceImpl extends SuperServiceImpl<TPersonAptitudeDao, TPersonAptitude> implements TPersonAptitudeService {
    @Autowired(required = false)
    private TPersonAptitudeDao tPersonAptitudeDao;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysOrgService sysOrgService;
    @Autowired
    private SysRuleService sysRuleService;
    @Autowired
    private SysDictDataController sysDictDataController;
    @Autowired
    private TSysFileService tSysFileService;

    @Override
    public BaseResponse<TPersonAptitude> addEntity(TPersonAptitudeParam addRequest) throws Exception {
        BaseResponse<TPersonAptitude> baseResponse = new BaseResponse<>();
        if (ObjectHelper.isNotEmpty(addRequest)) {
            SysUser sysUser = sysUserService.getById(addRequest.getPersonId());
            String orgId = ContextUtils.getLoginUser().getOrgId();
            SysOrg sysOrg = sysOrgService.getById(orgId);
            List<TPersonAptitude> tPersonAptitudes = addRequest.getTPersonAptitudes();
            List<TPersonAptitude> aptitudes = new ArrayList<>();
            for (TPersonAptitude tPersonAptitude : tPersonAptitudes) {
                // 资质有效期
                String aptitudeValid = tPersonAptitude.getAptitudeValid();
                // 获评时间
                String registerData = tPersonAptitude.getRegisterData();
                if (!"1".equals(tPersonAptitude.getIsLongTimeValid())) {
                    if (aptitudeValid.compareTo(registerData) < 0) {
                        throw new BusinessException("有效日期不能小于获取日期");
                    }
                }
                TPersonAptitude data = new TPersonAptitude();
                data.setPersonId(addRequest.getPersonId());
                data.setDeptId(addRequest.getDeptId());
                data.setOrgName(sysOrg.getOrgName());
                String id = IdHelper.getId32bit();
                data.setId(id);
                data.setAptitudeName(tPersonAptitude.getAptitudeName());
                data.setPersonName(sysUser.getUserName());
                data.setRegisterData(tPersonAptitude.getRegisterData());
                data.setIsLongTimeValid(tPersonAptitude.getIsLongTimeValid());
                data.setOrgId(sysOrg.getOrgId());
                data.setAptitudeStatus("1");
                data.setAptitudeValid(tPersonAptitude.getAptitudeValid());
                data.setRefId(tPersonAptitude.getRefId());
                if ("1".equals(data.getIsLongTimeValid())) {
                    data.setAptitudeValid("长期有效");
                }
                aptitudes.add(data);
            }
            checkAptitude(aptitudes);
            boolean result = this.saveBatch(aptitudes);
            if (result) {
                TPersonAptitude newEntity = new TPersonAptitude();
//                newEntity.setId(id);
                baseResponse.setData(newEntity);
            }
        }
        return baseResponse;
    }

    /**
     * 检查资质有效性
     */
    private void checkAptitude(List<TPersonAptitude> aptitudes) throws Exception {
        for (TPersonAptitude aptitude : aptitudes) {
            List<TPersonAptitude> list = this.list(new QueryWrapper<TPersonAptitude>()
                    .eq(TPersonAptitude.DEPT_ID, aptitude.getDeptId())
                    .ne(TPersonAptitude.STATUS, BizConstants.STATUS_DELETE)
                    .eq(TPersonAptitude.PERSON_ID, aptitude.getPersonId())
                    .eq(TPersonAptitude.APTITUDE_NAME, aptitude.getAptitudeName())
            );
            if (ObjectHelper.isNotEmpty(list)) {
                throw new BusinessException("此人已存在该资质");
            }
        }
        Map<String, List<TPersonAptitude>> collect = aptitudes.stream().collect(Collectors.groupingBy(item -> item.getPersonId() + item.getAptitudeName()));
        for (String s : collect.keySet()) {
            List<TPersonAptitude> aptitudeList = collect.get(s);
            if (aptitudeList.size() > 1) {
                throw new BusinessException("请勿重复添加相同资质");
            }
        }
    }

    @Override
    public BaseResponse<List<TPersonAptitude>> getAptitude(TPersonAptitude addRequest) {
        BaseResponse<List<TPersonAptitude>> baseResponse = new BaseResponse<>();
        if (StringHelper.isNotEmpty(addRequest.getDeptId()) && StringHelper.isNotEmpty(addRequest.getPersonId())) {
            UserInfo loginUser = ContextUtils.getLoginUser();
            List<TPersonAptitude> list = this.list(new QueryWrapper<TPersonAptitude>()
                    .eq(TPersonAptitude.DEPT_ID, addRequest.getDeptId())
                    .ne(TPersonAptitude.STATUS, BizConstants.STATUS_DELETE)
                    .eq(TPersonAptitude.PERSON_ID, addRequest.getPersonId())
                    .select(TPersonAptitude.APTITUDE_NAME)
            );
            baseResponse.setData(list);
        }
        return baseResponse;
    }

    @Override
    public BaseResponse<TPersonAptitudeDto> getByIds(String id) {
        BaseResponse<TPersonAptitudeDto> baseResponse = new BaseResponse<>();
        if (StringHelper.isEmpty(id)) {
            return baseResponse;
        }
        TPersonAptitude data = this.getById(id);
        TPersonAptitudeDto aptitudeDto = BeanHelper.beanToBean(data, TPersonAptitudeDto.class);

        String refId = data.getRefId();
        if (StringUtils.isBlank(refId)){
            baseResponse.setData(aptitudeDto);
            return baseResponse;
        }
        String[] split = refId.split(",");
        List<FileDTO> list = new ArrayList<>();
        for (String s : split) {
            FileDTO fileDTO = new FileDTO();
            TSysFile tSysFile = tSysFileService.getById(s);
            if (tSysFile != null && !(tSysFile.getStatus().equals("1"))) {
                fileDTO.setFilePath(tSysFile.getFilePath());
                fileDTO.setFileName(tSysFile.getFileName());
                fileDTO.setFileDowName(tSysFile.getFileDowName());
                fileDTO.setFileId(s);
                list.add(fileDTO);
            }
        }
        aptitudeDto.setFileDTOS(list);
        baseResponse.setData(aptitudeDto);
        return baseResponse;


    }

    @Override
    public BaseResponse<BizGeneralResponse> updateEntity(TPersonAptitude updateRequest) throws Exception {
        BaseResponse<BizGeneralResponse> baseResponse = new BaseResponse<>();
        if (ObjectHelper.isNotEmpty(updateRequest) && StringHelper.isNotEmpty(updateRequest.getId())) {
            TPersonAptitude data = BeanHelper.beanToBean(updateRequest, TPersonAptitude.class);
//            if ("1".equals(data.getIsLongTimeValid()) && StringHelper.isNotEmpty(data.getAptitudeValid())) {
//                throw new BusinessException("资质已长期有效");
//            }
            TPersonAptitude aptitude = this.getById(updateRequest.getId());
            // 资质有效期
            String aptitudeValid = updateRequest.getAptitudeValid();
            // 获评时间
            String registerData = updateRequest.getRegisterData();
            if (!"1".equals(updateRequest.getIsLongTimeValid())) {
                if (aptitudeValid.compareTo(registerData) < 0) {
                    throw new BusinessException("有效日期不能小于获取日期");
                }
            }
            if (!updateRequest.getAptitudeName().equals(aptitude.getAptitudeName())) {
                List<TPersonAptitude> list = this.list(new QueryWrapper<TPersonAptitude>()
                        .eq(TPersonAptitude.DEPT_ID, data.getDeptId())
                        .ne(TPersonAptitude.STATUS, BizConstants.STATUS_DELETE)
                        .eq(TPersonAptitude.PERSON_ID, data.getPersonId())
                        .eq(TPersonAptitude.APTITUDE_NAME, data.getAptitudeName())
                );
                if (ObjectHelper.isNotEmpty(list)) {
                    throw new BusinessException("此人已存在该资质");
                }
            }
            if ("1".equals(data.getIsLongTimeValid())) {
                data.setAptitudeValid("长期有效");
            }
            boolean result = this.updateById(data);
            baseResponse.setData(
                    BizGeneralResponse.builder().result(TypeHelper.castToString(result)).build());
        }
        return baseResponse;
    }

    @Override
    public BaseResponse<BizGeneralResponse> deleteEntity(TPersonAptitudeDelParam deleteRequest) {
        BaseResponse<BizGeneralResponse> baseResponse = new BaseResponse<>();
        if (ObjectHelper.isNotEmpty(deleteRequest) && StringHelper.isNotEmpty(deleteRequest.getId())) {
            TPersonAptitude data = new TPersonAptitude();
            data.setId(deleteRequest.getId());
            data.setStatus(BizConstants.STATUS_DELETE);
            boolean result = this.updateById(data);
            baseResponse.setData(
                    BizGeneralResponse.builder().result(TypeHelper.castToString(result)).build());
        }
        return baseResponse;
    }

    @Override
    public BaseResponse<List<DataStatistics>> AptitudeStatistics(TPersonAptitudeParam addRequest) {
        List<String> orgIds = addRequest.getOrgIds();
        if (ObjectHelper.isEmpty(orgIds)) {
            QueryWrapper<TPersonAptitude> wrapper = new QueryWrapper<>();
            String rule = sysRuleService.dataRuleScope(DefaultRule.DEPT_ALL.name());
            if (StringUtils.isNotEmpty(rule)) {
                wrapper.apply(rule);
            }
            List<TPersonAptitude> list = list(wrapper);
            List<String> strings = new ArrayList<>();
            for (TPersonAptitude tPersonAptitude : list) {
                String orgId = tPersonAptitude.getOrgId();
                strings.add(orgId);
            }
            orgIds = strings;
        }
        BaseResponse<List<DataStatistics>> baseResponse = new BaseResponse<>();
        // 获取筛选企业所有资质
        List<TPersonAptitude> list = this.list(new QueryWrapper<TPersonAptitude>()
                .in(TPersonAptitude.ORG_ID, orgIds)
                .ne(TPersonAptitude.STATUS, BizConstants.STATUS_DELETE)
        );
        Map<String, List<TPersonAptitude>> collect = list.stream().collect(Collectors.groupingBy(TPersonAptitude::getAptitudeName));
        // 资质名称集合
        List<DataStatistics> arrayList = new ArrayList<>();
        for (String key : collect.keySet()) {
            DataStatistics dataStatistics = new DataStatistics();
            //  存入资质名称
            dataStatistics.setAptitudeName(key);
            // 根据资质名称获取对应资质
            List<TPersonAptitude> aptitudes = collect.get(key);
            AptitudeCount aptitudeCount = new AptitudeCount();
            int validCount = 0;
            int invalidCount = 0;
            for (TPersonAptitude aptitude : aptitudes) {
                // 资质状态
                String aptitudeStatus = aptitude.getAptitudeStatus();
                if ("1".equals(aptitudeStatus)) {
                    validCount++;
                } else {
                    invalidCount++;
                }
            }
            aptitudeCount.setValidCount(validCount);
            aptitudeCount.setInvalidCount(invalidCount);
            ArrayList<AptitudeCount> aptitudeCounts = new ArrayList<>();
            aptitudeCounts.add(aptitudeCount);
            dataStatistics.setAptitudeCounts(aptitudeCounts);
            arrayList.add(dataStatistics);
        }
        baseResponse.setData(arrayList);
        return baseResponse;
    }

    @Override
    public BaseResponse<BizGeneralResponse> AptitudeStatus() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        // 当前时间
        String format = simpleDateFormat.format(date);
        String rule = sysRuleService.dataRuleScope(DefaultRule.DEPT_SUB.name());
        // 获取资质
        List<TPersonAptitude> list = this.list(
                new QueryWrapper<TPersonAptitude>()
                        .ne(TPersonAptitude.STATUS, BizConstants.STATUS_DELETE)
                        .apply(rule)

        );
        List<TPersonAptitude> aptitudeList = new ArrayList<>();
        for (TPersonAptitude tPersonAptitude : list) {
            TPersonAptitude tPersonAptitude1 = BeanHelper.beanToBean(tPersonAptitude, TPersonAptitude.class);
            if (tPersonAptitude1.getAptitudeValid().compareTo(format) < 0) {
                tPersonAptitude1.setAptitudeStatus("2");
            } else {
                tPersonAptitude1.setAptitudeStatus("1");
            }
            aptitudeList.add(tPersonAptitude1);
        }
        this.saveOrUpdateBatch(aptitudeList);
        return null;
    }

    @Override
    public BaseResponse<BizGeneralResponse> AptitudeExport(MultipartFile file) throws Exception {
        BaseResponse<BizGeneralResponse> baseResponse = new BaseResponse<>();
        UserInfo loginUser = ContextUtils.getLoginUser();
        SysOrg sysOrg = sysOrgService.getById(loginUser.getOrgId());
        Workbook workbook = null;
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            // 读取Excel⽂件⼯作表
            workbook = PoiExcelUtils.readFile(inputStream, file.getOriginalFilename());
            //取得第⼀个⼯作表
            Sheet sheet = workbook.getSheetAt(0);
            //报表上传的每条数据
            List<Map<Integer, Object>> list = PoiExcelUtils.getBody(sheet, 9, 2);
            List<TPersonAptitude> tPersonAptitudes = new ArrayList<>();
            for (Map<Integer, Object> integerObjectMap : list) {
                TPersonAptitude tPersonAptitude = new TPersonAptitude();
                // 企业名称
                String orgName = integerObjectMap.get(0).toString();
                if (ObjectHelper.isEmpty(orgName)) {
                    continue;
                }
                tPersonAptitude.setOrgName(orgName);
                // 企业id
                String orgCode = integerObjectMap.get(1).toString();
                if (!orgName.equals(sysOrg.getOrgName()) || !orgCode.equals(sysOrg.getOrgCode())) {
                    throw new BusinessException("请上传本单位人员资质" + orgName + "-" + orgCode);
                }
                SysOrg org = sysOrgService.getOne(new QueryWrapper<SysOrg>().eq("org_code", orgCode).eq("status", "0"));
                if (org != null) {
                    tPersonAptitude.setOrgId(org.getOrgId());
                }
                // 人员姓名
                String personName = integerObjectMap.get(2).toString();
                tPersonAptitude.setPersonName(personName);
                // 人员id
                String personId = integerObjectMap.get(3).toString();
                tPersonAptitude.setPersonId(personId);
                // 部门名称
                String deptName = integerObjectMap.get(4).toString();
                SysUser user = sysUserService.getById(personId);
                if (ObjectHelper.isEmpty(user) || !personName.equals(user.getUserName())) {
                    throw new BusinessException("查无此人" + user.getUserId() + "-" + user.getUserName());
                }
                // 部门id
                String deptId = user.getDeptId();
                SysOrg byId = sysOrgService.getById(deptId);
                if (!deptName.equals(byId.getOrgName())) {
                    throw new BusinessException("此部门查无此人" + deptName);
                }
                tPersonAptitude.setDeptId(deptId);
                // 资质名称
                String integerName = integerObjectMap.get(5).toString();
                tPersonAptitude.setAptitudeName(integerName);
                SysDictDataRequest sysDictDataRequest = new SysDictDataRequest();
                sysDictDataRequest.setDictType("aptitude_type");
                BaseResponse<SysDictDataComplexResponse> sysDictDataComplexResponseBaseResponse = sysDictDataController.listDataByType(sysDictDataRequest);
                List<SysDictDataListResponse> data = sysDictDataComplexResponseBaseResponse.getData().getData();
                List<String> dictValue = new ArrayList<>();
                for (SysDictDataListResponse dict : data) {
                    dictValue.add(dict.getDictValue());
                }
                if (!dictValue.contains(integerName)) {
                    throw new BusinessException("请填写正确的资质名称" + integerName);
                }
                // 获评日期
                String s = integerObjectMap.get(6).toString();
                String s2 = s.replaceAll("/", "-");
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                Date parse = simpleDateFormat.parse(s2);
                String format = simpleDateFormat.format(parse);
                tPersonAptitude.setRegisterData(format);
                // 资质是否长期有效
                String s1 = integerObjectMap.get(7).toString();
                tPersonAptitude.setAptitudeValid(integerObjectMap.get(8).toString());
                tPersonAptitude.setAptitudeStatus("1");
                if ("是".equals(s1)) {
                    tPersonAptitude.setIsLongTimeValid("1");
                    tPersonAptitude.setAptitudeValid("长期有效");
                } else if ("否".equals(s1)) {
                    tPersonAptitude.setIsLongTimeValid("0");
                }
                // 有效期
                tPersonAptitudes.add(tPersonAptitude);
            }
            // 检查资质有效性
            checkAptitude(tPersonAptitudes);
            this.saveBatch(tPersonAptitudes);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != workbook) {
                    workbook.close();
                }
                if (null != inputStream) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return baseResponse;
    }
}
