/*
 *    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 cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.EasyExcel;
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.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TGzOfferInfo;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TRegisteWarningEmployee;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.EmployeeRegistrationPreMapper;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.TGzOfferInfoMapper;
import com.yifu.cloud.plus.v1.yifu.archives.service.TGzOfferInfoService;
import com.yifu.cloud.plus.v1.yifu.archives.service.TRegisteWarningEmployeeService;
import com.yifu.cloud.plus.v1.yifu.archives.vo.MessageTempleteVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TGzOfferInfoImportVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TGzOfferInfoVo;
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.core.util.alisms.AliSmsResult;
import com.yifu.cloud.plus.v1.yifu.common.core.util.alisms.RegistParamVo;
import com.yifu.cloud.plus.v1.yifu.common.core.util.alisms.YiFuSmsUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 瓜子offer信息接收表
 *
 * @author chenyx
 * @date 2025-06-11 15:58:37
 */
@Log4j2
@Service
@RequiredArgsConstructor
public class TGzOfferInfoServiceImpl extends ServiceImpl<TGzOfferInfoMapper, TGzOfferInfo> implements TGzOfferInfoService {

	private final TRegisteWarningEmployeeService employeeService;

	private final EmployeeRegistrationPreMapper registrationPreMapper;

    /**
     * 瓜子offer信息接收表简单分页查询
     * @param tGzOfferInfo 瓜子offer信息接收表
     * @return IPage<TGzOfferInfoVo>
     */
    @Override
    public IPage<TGzOfferInfoVo> getTGzOfferInfoPage(Page<TGzOfferInfoVo> page, TGzOfferInfoVo tGzOfferInfo){
		return baseMapper.getTGzOfferInfoPage(page,tGzOfferInfo);
    }

	@Override
	public TGzOfferInfo getDataById(Integer id) {
		return this.getInfoCommon(id);
	}

	/**
	 * 修改瓜子offer信息
	 *
	 * @param tGzOfferInfo 字典
	 * @return R<String>
	 */
	@Override
	public R<String> updateDataById(TGzOfferInfo tGzOfferInfo) {
		YifuUser user = SecurityUtils.getUser();
		if (user == null || Common.isEmpty(user.getId())) {
			return R.failed(CommonConstants.PLEASE_LOG_IN);
		}
		TGzOfferInfo findInfo = this.getInfoCommon(tGzOfferInfo.getId());
		if (Common.isEmpty(findInfo)){
			return R.failed(CommonConstants.ERROR_NO_DOMAIN);
		}

		tGzOfferInfo.setUpdateBy(user.getId());
		tGzOfferInfo.setUpdateTime(LocalDateTime.now());
		this.updateById(tGzOfferInfo);

		// todo 记录offer操作日志

		return R.ok(CommonConstants.RESULT_DATA_SUCESS);
	}

	/**
	 * 瓜子offer手动状态更新
	 *
	 * @param tGzOfferInfo 字典
	 * @return R<String>
	 */
	@Override
	public R<String> updateStatus(TGzOfferInfo tGzOfferInfo) {
		YifuUser user = SecurityUtils.getUser();
		if (user == null || Common.isEmpty(user.getId())) {
			return R.failed(CommonConstants.PLEASE_LOG_IN);
		}
		if(Common.isEmpty(tGzOfferInfo.getId())){
			return R.failed(CommonConstants.PARAM_IS_NOT_EMPTY);
		}
		if(Common.isEmpty(tGzOfferInfo.getOfferStatus())){
			return R.failed("更新状态不能为空");
		}
		TGzOfferInfo findInfo = this.getInfoCommon(tGzOfferInfo.getId());
		if (Common.isEmpty(findInfo)){
			return R.failed(CommonConstants.ERROR_NO_DOMAIN);
		}
		// 更新为同一状态的提示操作失败
		if(findInfo.getOfferStatus().equals(tGzOfferInfo.getOfferStatus())){
			return R.failed("当前Offer更新状态失败，请刷新页面后重试");
		}
		// 当前Offer更新状态,无法再发起更新：5：拒绝Offer、10：取消offer、8：合同审核通过、99：已归档
		String[] forbidStatusArr = {"5", "10", "8","99"};
		if (ArrayUtils.contains(forbidStatusArr, findInfo.getOfferStatus())) {
			return R.failed("当前Offer更新状态,无法再发起更新");
		}
		// 获取当前状态下，允许更新的状态列表
		List<String> allowUpdateStatusList = this.allowUpdateStatus(findInfo.getOfferStatus());
		if(!allowUpdateStatusList.contains(tGzOfferInfo.getOfferStatus())){
			return R.failed("当前Offer更新状态失败，禁止更新为所选状态，请刷新页面后重试");
		}
		// 更新状态
		LambdaUpdateWrapper<TGzOfferInfo> updateOfferWrapper = new LambdaUpdateWrapper<>();
		updateOfferWrapper.eq(TGzOfferInfo::getId, tGzOfferInfo.getId())
				.set(TGzOfferInfo::getOfferStatus, tGzOfferInfo.getOfferStatus())
				.set(TGzOfferInfo::getUpdateTime, LocalDateTime.now())
				.set(TGzOfferInfo::getUpdateBy, user.getId());
		this.update(null, updateOfferWrapper);

		// todo 记录offer操作日志

		return R.ok(CommonConstants.RESULT_DATA_SUCESS);
	}

	/**
	 * 获取当前状态下，允许更新的状态列表
	 *
	 * @param orgStatus 当前状态
	 * @return List<String> 允许更新的状态列表
	 */
	private List<String> allowUpdateStatus(String orgStatus){
		List<String> allowUpdateStatusList = new ArrayList<>();
		// 3：待发送Offer
		if(CommonConstants.THREE_STRING.equals(orgStatus)){
			// 可更新为：4：待接受Offer、10：取消offer
			allowUpdateStatusList.add(CommonConstants.FOUR_STRING);
			allowUpdateStatusList.add(CommonConstants.TEN_STRING);
		}
		// 4：待接受Offer
		if(CommonConstants.FOUR_STRING.equals(orgStatus)){
			// 可更新为：5：拒绝Offer、7：接受offer、10：取消offer
			allowUpdateStatusList.add(CommonConstants.FIVE_STRING);
			allowUpdateStatusList.add(CommonConstants.SEVEN_STRING);
			allowUpdateStatusList.add(CommonConstants.TEN_STRING);
		}
		// 7：接受Offer
		if(CommonConstants.SEVEN_STRING.equals(orgStatus)){
			// 可更新为：98：信息待收集、10：取消offer
			allowUpdateStatusList.add("98");
			allowUpdateStatusList.add(CommonConstants.TEN_STRING);
		}
		// 98：信息待收集、9：候选人填写信息、12：候选人信息审核、97：候选人审核通过、13：待签署
		if("98".equals(orgStatus) || CommonConstants.NINE_STRING.equals(orgStatus)
				|| CommonConstants.TWELVE_STRING.equals(orgStatus) || "97".equals(orgStatus)
				|| CommonConstants.THIRTEEN_STRING.equals(orgStatus)){
			// 可更新为：10：取消offer
			allowUpdateStatusList.add(CommonConstants.TEN_STRING);
		}

		return allowUpdateStatusList;
	}

	private TGzOfferInfo getInfoCommon(Integer id){
		return this.getOne(Wrappers.<TGzOfferInfo>query().lambda()
				.eq(TGzOfferInfo::getId, id)
				.eq(TGzOfferInfo::getDelFlag, CommonConstants.ZERO_STRING)
				.last(CommonConstants.LAST_ONE_SQL));
	}


	@Override
	public R<List<ErrorMessage>> importDiy(InputStream inputStream) {
		List<ErrorMessage> errorMessageList = new ArrayList<>();
		ExcelUtil<TGzOfferInfoImportVo> util1 = new ExcelUtil<>(TGzOfferInfoImportVo.class);
		// 写法2：
		// 匿名内部类 不用额外写一个DemoDataListener
		// 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
		try {
			EasyExcel.read(inputStream, TGzOfferInfoImportVo.class, new ReadListener<TGzOfferInfoImportVo>() {
				/**
				 * 单次缓存的数据量
				 */
				public static final int BATCH_COUNT = CommonConstants.BATCH_COUNT;
				/**
				 *临时存储
				 */
				private List<TGzOfferInfoImportVo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

				@Override
				public void invoke(TGzOfferInfoImportVo data, AnalysisContext context) {
					ReadRowHolder readRowHolder = context.readRowHolder();
					Integer rowIndex = readRowHolder.getRowIndex();
					data.setRowIndex(rowIndex+1);
					ErrorMessage errorMessage = util1.checkEntity(data, data.getRowIndex());
					if (Common.isNotNull(errorMessage)){
						errorMessageList.add(errorMessage);
					}else {
						cachedDataList.add(data);
					}
					if (cachedDataList.size() >= BATCH_COUNT) {
						saveData();
						// 存储完成清理 list
						cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
					}
				}
				@Override
				public void doAfterAllAnalysed(AnalysisContext context) {
					saveData();
				}

				/**
				 * 加上存储数据库
				 */
				private void saveData() {
					log.info("{}条数据，开始存储数据库！", cachedDataList.size());
					importTDispatchExportLog(cachedDataList,errorMessageList);
					log.info("存储数据库成功！");
				}
			}).sheet().doRead();
		}catch (Exception e){
			log.error(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR,e);
			return R.failed(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR);
		}
		return  R.ok(errorMessageList);
	}

	@Override
	public R sendOfferAlert(TGzOfferInfoVo tGzOfferInfo) {
		//获取所有满足条件的未发送offer提醒的数据
		if (Common.isNotNull(tGzOfferInfo)) {
			tGzOfferInfo.setOfferStatus(CommonConstants.FOUR_STRING);
			List<TGzOfferInfoVo> offerList = baseMapper.getTGzOfferInfoSendAlertList(tGzOfferInfo);
			if (Common.isNotNull(offerList) && !offerList.isEmpty()) {
				if (Common.isNotNull(offerList) && offerList.size() >200) {
					return R.failed("短信批量发送单次最多两百条");
				}
				//获取短信待发放和信息待填写的数据
				List<String> errorList = new ArrayList<>();
				List<RegistParamVo> params = new ArrayList<>();
				List<String> phones = new ArrayList<>();
				for (TGzOfferInfoVo sendVo : offerList) {
					RegistParamVo paramVo = new RegistParamVo();
					AliSmsResult res;
					paramVo.setName(sendVo.getName());
					phones.add(sendVo.getPhone());
					//生成短信发送的记录
					TRegisteWarningEmployee smsEmployee = new TRegisteWarningEmployee();
					smsEmployee.setEmpName(sendVo.getName());
					smsEmployee.setEmpPhone(sendVo.getPhone());
					smsEmployee.setEmpIdcard(sendVo.getNationalId());
					smsEmployee.setSendDate(DateUtil.getCurrentDateTime());
					smsEmployee.setSendMethod(CommonConstants.ONE_INT);
					smsEmployee.setWarningId(sendVo.getId().toString());
					smsEmployee.setType(CommonConstants.THREE_STRING);
					employeeService.save(smsEmployee);
					params.add(paramVo);
					res = sendMessage(phones, params);
					if (null != res && null != res.getBizId()) {
						//发送成功
						smsEmployee.setBizId(res.getBizId());
						smsEmployee.setMessage(res.getMessage());
						employeeService.updateById(smsEmployee);
						//更新Offer信息接收表发送状态为已发送
						LambdaUpdateWrapper<TGzOfferInfo> updateWrapper = new LambdaUpdateWrapper<>();
						updateWrapper.in(TGzOfferInfo::getId, sendVo.getId())
								.in(TGzOfferInfo::getOfferSendStatus, CommonConstants.ONE_STRING)
								.set(TGzOfferInfo::getOfferSendStatus, CommonConstants.ZERO_STRING);
						// 执行更新操作
						this.update(updateWrapper);
					} else {
						smsEmployee.setMessage("短信发送失败");
						employeeService.updateById(smsEmployee);
						errorList.add("短信发送失败");
					}
				}
				if (!errorList.isEmpty() && errorList.stream().allMatch(e->e.equals("短信发送失败"))) {
					return R.ok("短信发送失败");
				}
				return R.ok();
			} else {
				return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
			}
		}
		return R.failed(CommonConstants.PARAM_IS_NOT_ERROR);
	}


	/**
	 * @Description: 批量发送短信
	 * @Author: huych
	 * @Date: 2025/3/18 17:02
	 * @return:
	 **/
	public AliSmsResult sendMessage (List<String> phones,List<RegistParamVo> params ) {
		List<String> signNames = new ArrayList<>();
		MessageTempleteVo templeteVo = registrationPreMapper.selectTempleteVo(CommonConstants.TWO_STRING);
		for (int i=0;i<phones.size();i++){
			signNames.add(templeteVo.getSignName());
		}
		return YiFuSmsUtil.sendRegistBatchSms(phones, params, signNames, templeteVo.getTempleteCode());
	}

	private void importTDispatchExportLog(List<TGzOfferInfoImportVo> excelVOList, List<ErrorMessage> errorMessageList) {
		// 个性化校验逻辑
		ErrorMessage errorMsg;
		// 执行数据插入操作 组装
		TGzOfferInfoImportVo excel;
		for (int i = 0; i < excelVOList.size(); i++) {
			excel = excelVOList.get(i);
			// 插入
			insertExcel(excel);
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(), CommonConstants.SAVE_SUCCESS));
		}
	}
	/**
	 * 插入excel bad record
	 */
	private void insertExcel(TGzOfferInfoImportVo excel) {
		TGzOfferInfo insert = new TGzOfferInfo();
		BeanUtil.copyProperties(excel, insert);
		this.save(insert);
	}

}
