/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the yifu4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.yifu.cloud.plus.v1.yifu.archives.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.alibaba.excel.EasyExcelFactory;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.AreaMap;
import com.yifu.cloud.plus.v1.yifu.archives.entity.*;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.*;
import com.yifu.cloud.plus.v1.yifu.archives.service.TAttaInfoService;
import com.yifu.cloud.plus.v1.yifu.archives.service.TGzEmpInfoService;
import com.yifu.cloud.plus.v1.yifu.archives.service.TGzOfferInfoService;
import com.yifu.cloud.plus.v1.yifu.archives.util.IdCardUtil;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TGzEmpInfoExportMain;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TGzOfferInfoExportDetailVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TGzOfferInfoExportMainVo;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CacheConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprCheckProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprSalaryProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprUpmsProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.HttpDaprUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import com.yifu.cloud.plus.v1.yifu.common.core.util.ErrorMessage;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TGzEmpInfoSearchVo;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.HashMap;
import java.net.URL;
import java.util.List;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ArrayUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.*;
import com.yifu.cloud.plus.v1.yifu.common.mybatis.base.BaseEntity;

import javax.servlet.ServletOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Map;

/**
 * 瓜子档案表
 *
 * @author chenyx
 * @date 2025-06-13 15:19:03
 */
@Log4j2
@Service
@RequiredArgsConstructor
@EnableConfigurationProperties(DaprUpmsProperties.class)
public class TGzEmpInfoServiceImpl extends ServiceImpl<TGzEmpInfoMapper, TGzEmpInfo> implements TGzEmpInfoService {

	private final TGzOfferInfoService gzOfferInfoService;

	private final TGzEmpContactInfoMapper gzEmpContactInfoMapper;

	private final TGzEmpEducationMapper gzEmpEducationMapper;

	private final TGzEmpFamilyMapper gzEmpFamilyMapper;

	private final TGzEmpSkillMapper gzEmpSkillMapper;

	private final TGzEmpWorkMapper gzEmpWorkMapper;

	private final TAttaInfoService attaInfoService;

	// 拿区域
	private final DaprUpmsProperties daprUpmsProperties;

	@Autowired
	private OSSUtil ossUtil;


	/**
	 * 瓜子档案表简单分页查询
	 *
	 * @param tGzEmpInfo 瓜子档案表
	 * @return
	 */
	@Override
	public IPage<TGzEmpInfo> getTGzEmpInfoPage(Page<TGzEmpInfo> page, TGzEmpInfoSearchVo tGzEmpInfo) {
		return baseMapper.getTGzEmpInfoPage(page, tGzEmpInfo);
	}

	/**
	 * 通过OfferId查询瓜子档案详情
	 *
	 * @param offerId OfferId
	 * @return R
	 */
	@Override
	public R<TGzEmpInfoSearchVo> getInfoByOfferId(Integer offerId) {
		TGzEmpInfoSearchVo gzEmpInfoVo = new TGzEmpInfoSearchVo();

		TGzOfferInfo gzOfferInfo = gzOfferInfoService.getOne(Wrappers.<TGzOfferInfo>query().lambda()
				.eq(TGzOfferInfo::getId, offerId)
				.eq(TGzOfferInfo::getDelFlag, CommonConstants.ZERO_STRING)
				.last(CommonConstants.LAST_ONE_SQL));
		if(Common.isEmpty(gzOfferInfo)){
			return R.failed("数据异常，禁止操作");
		}
		if(!CommonConstants.NINE_STRING.equals(gzOfferInfo.getOfferStatus())){
			return R.failed("当前Offer不符合档案采集状态，禁止操作");
		}

		TGzEmpInfo gzEmpInfo = this.getOne(Wrappers.<TGzEmpInfo>query().lambda()
				.eq(TGzEmpInfo::getOfferId, offerId)
				.eq(TGzEmpInfo::getDelFlag, CommonConstants.ZERO_STRING)
				.last(CommonConstants.LAST_ONE_SQL));

		// 还未生成档案，取offer里的信息
		if(Common.isEmpty(gzEmpInfo)){
			gzEmpInfoVo.setBizId(gzEmpInfo.getBizId());
			gzEmpInfoVo.setOfferId(offerId);
			gzEmpInfoVo.setName(gzOfferInfo.getName());
			gzEmpInfoVo.setNameAc(gzOfferInfo.getNameAc());
			gzEmpInfoVo.setNationalIdType(gzOfferInfo.getNationalIdType());
			gzEmpInfoVo.setNationalId(gzOfferInfo.getNationalId());
			// 根据身份证得出 出生日期和性别
			if(Common.isNotNull(gzEmpInfoVo.getNationalId()) && gzEmpInfoVo.getNationalId().length() > 14){
				String idCard = gzEmpInfoVo.getNationalId();
				gzEmpInfoVo.setBirthdate(IdCardUtil.getBirthdate(idCard));
				// 性别: F:女,M:男
				if (idCard.length() > 17) {
					if (Integer.parseInt(idCard.substring(16, 17)) % 2 == 1) {
						gzEmpInfoVo.setSex("M");
					} else {
						gzEmpInfoVo.setSex("F");
					}
				}
			}
			gzEmpInfoVo.setPhone(gzOfferInfo.getPhone());
			gzEmpInfoVo.setMail(gzOfferInfo.getEmail());
			// 地址类型: 系统存默认值“现住址”:1A
			gzEmpInfoVo.setAddressType("1A");
		} else {
			BeanUtil.copyProperties(gzEmpInfo, gzEmpInfoVo);
			// 获取瓜子档案附属信息

			// 紧急联系人
			LambdaQueryWrapper<TGzEmpContactInfo> queryContactInfo = Wrappers.<TGzEmpContactInfo>lambdaQuery()
					.eq(TGzEmpContactInfo::getEmpId, gzEmpInfo.getId())
					.eq(TGzEmpContactInfo::getDelFlag, CommonConstants.ZERO_STRING)
					.eq(TGzEmpContactInfo::getPrimaryNid, "Y")
					.last(" limit 1 ");
			List<TGzEmpContactInfo> emergContactList = gzEmpContactInfoMapper.selectList(queryContactInfo);
			gzEmpInfoVo.setEmergContactList(emergContactList);
			// 教育经历
			LambdaQueryWrapper<TGzEmpEducation> queryEduInfo = Wrappers.<TGzEmpEducation>lambdaQuery()
					.eq(TGzEmpEducation::getEmpId, gzEmpInfo.getId())
					.eq(TGzEmpEducation::getDelFlag, CommonConstants.ZERO_STRING)
					.eq(TGzEmpEducation::getHighEduQualFlag, "Y")
					.last(" limit 1 ");
			List<TGzEmpEducation> eduList = gzEmpEducationMapper.selectList(queryEduInfo);
			gzEmpInfoVo.setEduExpList(eduList);

			// 工作经历列表
			LambdaQueryWrapper<TGzEmpWork> queryWorkInfo = Wrappers.<TGzEmpWork>lambdaQuery()
					.eq(TGzEmpWork::getEmpId, gzEmpInfo.getId())
					.eq(TGzEmpWork::getDelFlag, CommonConstants.ZERO_STRING)
					.orderByAsc(TGzEmpWork::getCreateTime).orderByAsc(TGzEmpWork::getId);
			List<TGzEmpWork> workList = gzEmpWorkMapper.selectList(queryWorkInfo);
			gzEmpInfoVo.setWorkExpList(workList);
			// 家庭成员列表
			LambdaQueryWrapper<TGzEmpFamily> queryFamilyInfo = Wrappers.<TGzEmpFamily>lambdaQuery()
					.eq(TGzEmpFamily::getEmpId, gzEmpInfo.getId())
					.eq(TGzEmpFamily::getDelFlag, CommonConstants.ZERO_STRING)
					.orderByAsc(TGzEmpFamily::getCreateTime).orderByAsc(TGzEmpFamily::getId);
			List<TGzEmpFamily> familyList = gzEmpFamilyMapper.selectList(queryFamilyInfo);
			gzEmpInfoVo.setFamilyList(familyList);
			// 技能证书列表
			LambdaQueryWrapper<TGzEmpSkill> querySkillInfo = Wrappers.<TGzEmpSkill>lambdaQuery()
					.eq(TGzEmpSkill::getEmpId, gzEmpInfo.getId())
					.eq(TGzEmpSkill::getDelFlag, CommonConstants.ZERO_STRING)
					.orderByAsc(TGzEmpSkill::getCreateTime).orderByAsc(TGzEmpSkill::getId);
			List<TGzEmpSkill> skillList = gzEmpSkillMapper.selectList(querySkillInfo);
			gzEmpInfoVo.setSkillList(skillList);

			// 附件
			List<TAttaInfo> attaInfos = attaInfoService.list(Wrappers.<TAttaInfo>query().lambda().eq(TAttaInfo::getDomainId, gzEmpInfo.getId()));
			if (Common.isNotNull(attaInfos)) {
				URL url;
				for (TAttaInfo atta : attaInfos) {
					url = ossUtil.getObjectUrl(null, atta.getAttaSrc());
					if (Common.isNotNull(url)) {
						atta.setAttaUrl(url.toString());
					}
				}
			}
			gzEmpInfoVo.setAttaList(attaInfos);
		}
		return R.ok(gzEmpInfoVo);
	}

	/**
	 * 瓜子档案表批量导出
	 *
	 * @param searchVo 瓜子档案表
	 * @return
	 */
	@Override
	public void listExport(HttpServletResponse response, TGzEmpInfoSearchVo searchVo) {
		String prfName = "瓜子员工档案信息";
		String fileName = prfName + DateUtil.getThisTime() + ".xlsx";
		//获取要导出的列表
		List<TGzEmpInfoExportMain> list = new ArrayList<>();
		long count = baseMapper.getTGzEmpInfoCount(searchVo);

		ServletOutputStream out = null;
		try {
			out = response.getOutputStream();
			response.setContentType(CommonConstants.MULTIPART_FORM_DATA);
			response.setCharacterEncoding("utf-8");
			response.setHeader(CommonConstants.CONTENT_DISPOSITION, CommonConstants.ATTACHMENT_FILENAME + URLEncoder.encode(fileName, CommonConstants.UTF8));
			Map<String,String> redisLabelMap = (Map<String, String>) RedisUtil.redis.opsForValue().get(CacheConstants.REDIS_DICT_LABLE);
			Map<String,String> idLabelMap = (Map<String, String>) RedisUtil.redis.opsForValue().get(CacheConstants.AREA_VALUE_ALL);
			if (Common.isEmpty(idLabelMap) || idLabelMap.isEmpty()) {
				R<AreaMap> areaListR = HttpDaprUtil.invokeMethodPost(daprUpmsProperties.getAppUrl(), daprUpmsProperties.getAppId()
						, "/area/inner/getAreaMapAll", "", AreaMap.class, SecurityConstants.FROM_IN);
				if (Common.isNotNull(areaListR)) {
					idLabelMap = areaListR.getData().getIdLabelMap();
				}
			}
			if (redisLabelMap != null && idLabelMap != null) {
				redisLabelMap.putAll(idLabelMap);
			}
			Map<String,String> nameAndDicTypeMap = new HashMap<>();
			ExcelUtil.getDictMapAndExp(TGzEmpInfoExportMain.class, nameAndDicTypeMap, redisLabelMap);
			ExcelWriter excelWriter = EasyExcelFactory.write(out, TGzEmpInfoExportMain.class).registerConverter(new DictConverter(nameAndDicTypeMap, redisLabelMap)).build();
			int index = 0;
			if (count > CommonConstants.ZERO_INT) {
				WriteSheet writeSheet;
				for (int i = 0; i <= count; i += CommonConstants.EXCEL_EXPORT_LIMIT){
					// 获取实际记录
					searchVo.setLimitStart(i);
					searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
					list = baseMapper.getTGzEmpInfoList(searchVo);
					if (Common.isNotNull(list)) {
						writeSheet = EasyExcelFactory.writerSheet(prfName + index).build();
						excelWriter.write(list, writeSheet);
						index++;
					}
					if (Common.isNotNull(list)) {
						list.clear();
					}
				}
			} else {
				WriteSheet writeSheet = EasyExcelFactory.writerSheet(prfName + index).build();
				excelWriter.write(list, writeSheet);
			}
			if (Common.isNotNull(list)) {
				list.clear();
			}
			out.flush();
			excelWriter.finish();
		} catch (Exception e) {
			log.error("执行异常", e);
		} finally {
			try {
				if (null != out) {
					out.close();
				}
			} catch (IOException e) {
				log.error("执行异常", e);
			}
		}
	}

	@Override
	public List<TGzEmpInfo> noPageDiy(TGzEmpInfoSearchVo searchVo) {
		LambdaQueryWrapper<TGzEmpInfo> wrapper = buildQueryWrapper(searchVo);
		List<String> idList = Common.getList(searchVo.getIds());
		if (Common.isNotNull(idList)) {
			wrapper.in(TGzEmpInfo::getId, idList);
		}
		if (searchVo.getLimitStart() >= 0 && searchVo.getLimitEnd() > 0) {
			wrapper.last(" limit " + searchVo.getLimitStart() + "," + searchVo.getLimitEnd());
		}
		wrapper.orderByDesc(BaseEntity::getCreateTime);
		return baseMapper.selectList(wrapper);
	}

	private Long noPageCountDiy(TGzEmpInfoSearchVo searchVo) {
		LambdaQueryWrapper<TGzEmpInfo> wrapper = buildQueryWrapper(searchVo);
		List<String> idList = Common.getList(searchVo.getIds());
		if (Common.isNotNull(idList)) {
			wrapper.in(TGzEmpInfo::getId, idList);
		}
		return baseMapper.selectCount(wrapper);
	}

	private LambdaQueryWrapper buildQueryWrapper(TGzEmpInfoSearchVo entity) {
		LambdaQueryWrapper<TGzEmpInfo> wrapper = Wrappers.lambdaQuery();

		if (Common.isNotNull(entity.getCreateName())) {
			wrapper.eq(TGzEmpInfo::getCreateName, entity.getCreateName());
		}
		return wrapper;
	}

}
