/*
 *    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.social.service.impl;

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.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.DateUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.social.entity.SysBaseSetInfo;
import com.yifu.cloud.plus.v1.yifu.social.entity.SysHouseHoldInfo;
import com.yifu.cloud.plus.v1.yifu.social.entity.SysPayProportion;
import com.yifu.cloud.plus.v1.yifu.social.mapper.SysBaseSetInfoMapper;
import com.yifu.cloud.plus.v1.yifu.social.mapper.SysHouseHoldInfoMapper;
import com.yifu.cloud.plus.v1.yifu.social.service.SysBaseSetInfoService;
import com.yifu.cloud.plus.v1.yifu.social.service.SysPayProportionService;
import com.yifu.cloud.plus.v1.yifu.social.service.TForecastLibraryService;
import com.yifu.cloud.plus.v1.yifu.social.service.TSocialLogService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 基数设置表
 *
 * @author hgw
 * @date 2022-07-11 18:21:23
 */
@RequiredArgsConstructor
@Service
public class SysBaseSetInfoServiceImpl extends ServiceImpl<SysBaseSetInfoMapper, SysBaseSetInfo> implements SysBaseSetInfoService {

	private final TSocialLogService tSocialLogService;

	private final SysPayProportionService sysPayProportionService;

	private final SysHouseHoldInfoMapper sysHouseHoldInfoMapper;
	/**
	 * 基数设置表简单分页查询
	 *
	 * @param sysBaseSetInfo 基数设置表
	 * @return
	 */
	@Override
	public IPage<SysBaseSetInfo> getSysBaseSetInfoPage(Page<SysBaseSetInfo> page, SysBaseSetInfo sysBaseSetInfo) {
		return baseMapper.getSysBaseSetInfoPage(page, sysBaseSetInfo);
	}

	@Override
	public R<String> saveSysBase(SysBaseSetInfo sysBaseSetInfo) {
		YifuUser user = SecurityUtils.getUser();
		if (null == user) {
			return R.failed("获取用户登录信息失败！");
		}
		SysBaseSetInfo baseSetInfo = null;
		SysBaseSetInfo lastBase = null;
		if (null != sysBaseSetInfo.getTown()) {
			baseSetInfo = this.getOne(Wrappers.<SysBaseSetInfo>query().lambda()
					.eq(SysBaseSetInfo::getBaseType, sysBaseSetInfo.getBaseType())
					.eq(SysBaseSetInfo::getDepartId, sysBaseSetInfo.getDepartId())
					.eq(SysBaseSetInfo::getTown, sysBaseSetInfo.getTown())
					.and(obj -> obj
							.ge(SysBaseSetInfo::getApplyStartDate, sysBaseSetInfo.getApplyStartDate())
							.or()
							.ge(SysBaseSetInfo::getApplyEndDate, sysBaseSetInfo.getApplyStartDate()))
					.last(CommonConstants.LAST_ONE_SQL));

			lastBase = this.getOne(Wrappers.<SysBaseSetInfo>query().lambda()
					.eq(SysBaseSetInfo::getBaseType, sysBaseSetInfo.getBaseType())
					.eq(SysBaseSetInfo::getDepartId, sysBaseSetInfo.getDepartId())
					.eq(SysBaseSetInfo::getTown, sysBaseSetInfo.getTown())
					.isNull(SysBaseSetInfo::getApplyEndDate)
					.last(CommonConstants.LAST_ONE_SQL));
		}
		if (null != sysBaseSetInfo.getCity() && null == sysBaseSetInfo.getTown()) {
			baseSetInfo = this.getOne(Wrappers.<SysBaseSetInfo>query().lambda()
					.eq(SysBaseSetInfo::getBaseType, sysBaseSetInfo.getBaseType())
					.eq(SysBaseSetInfo::getDepartId, sysBaseSetInfo.getDepartId())
					.eq(SysBaseSetInfo::getCity, sysBaseSetInfo.getCity())
					.isNull(SysBaseSetInfo::getTown)
					.and(obj -> obj
							.ge(SysBaseSetInfo::getApplyStartDate, sysBaseSetInfo.getApplyStartDate())
							.or()
							.ge(SysBaseSetInfo::getApplyEndDate, sysBaseSetInfo.getApplyStartDate()))
					.last(CommonConstants.LAST_ONE_SQL));

			lastBase = this.getOne(Wrappers.<SysBaseSetInfo>query().lambda()
					.eq(SysBaseSetInfo::getBaseType, sysBaseSetInfo.getBaseType())
					.eq(SysBaseSetInfo::getDepartId, sysBaseSetInfo.getDepartId())
					.eq(SysBaseSetInfo::getCity, sysBaseSetInfo.getCity())
					.isNull(SysBaseSetInfo::getTown)
					.isNull(SysBaseSetInfo::getApplyEndDate)
					.last(CommonConstants.LAST_ONE_SQL));
		}
		if (null != sysBaseSetInfo.getProvince() && null == sysBaseSetInfo.getCity()) {
			baseSetInfo = this.getOne(Wrappers.<SysBaseSetInfo>query().lambda()
					.eq(SysBaseSetInfo::getBaseType, sysBaseSetInfo.getBaseType())
					.eq(SysBaseSetInfo::getDepartId, sysBaseSetInfo.getDepartId())
					.eq(SysBaseSetInfo::getProvince, sysBaseSetInfo.getProvince())
					.isNull(SysBaseSetInfo::getCity)
					.and(obj -> obj
							.ge(SysBaseSetInfo::getApplyStartDate, sysBaseSetInfo.getApplyStartDate())
							.or()
							.ge(SysBaseSetInfo::getApplyEndDate, sysBaseSetInfo.getApplyStartDate()))
					.last(CommonConstants.LAST_ONE_SQL));

			lastBase = this.getOne(Wrappers.<SysBaseSetInfo>query().lambda()
					.eq(SysBaseSetInfo::getBaseType, sysBaseSetInfo.getBaseType())
					.eq(SysBaseSetInfo::getDepartId, sysBaseSetInfo.getDepartId())
					.eq(SysBaseSetInfo::getProvince, sysBaseSetInfo.getProvince())
					.isNull(SysBaseSetInfo::getCity)
					.isNull(SysBaseSetInfo::getApplyEndDate)
					.last(CommonConstants.LAST_ONE_SQL));
		}
		if (null != baseSetInfo) {
			return R.failed("对应户、地市、有效期的基数配置已存在！");
		}

		// 将上一个无截止月的增加截止月（本次起始月的上一个月）
		if (lastBase != null) {
			lastBase.setApplyEndDate(DateUtil.addDayByDate(sysBaseSetInfo.getApplyStartDate(), -1));
			this.updateById(lastBase);
		}
		this.saveOrUpdateBaseAndFundPro(sysBaseSetInfo, null);
		return R.ok();
	}

	@Override
	public R<String> updateSysBase(SysBaseSetInfo sysBaseSetInfo) {
		YifuUser user = SecurityUtils.getUser();
		if (null == user) {
			return R.failed("获取用户登录信息失败！");
		}
		SysBaseSetInfo old = this.getById(sysBaseSetInfo.getId());
		if (old == null || Common.isEmpty(old.getId())) {
			return R.failed("根据id未找到基数配置！" + sysBaseSetInfo.getId());
		} else {
			List<SysPayProportion> payProportionList = sysPayProportionService.getSysPayProportionByBaseId(sysBaseSetInfo.getId());
			old.setFundProList(payProportionList);
		}
		// 2023-2-16 09:38:24 晨会上产品经理倩倩确认，编辑时，时间日期不可编辑。
		/*int count = baseMapper.getCountByEdit(sysBaseSetInfo)
		if count > CommonConstants.ZERO_INT)
			return R.failed("对应户、地市、有效期的基数配置已存在！")
		*/

		this.saveOrUpdateBaseAndFundPro(sysBaseSetInfo, old);
		int type = CommonConstants.ONE_INT;
		if (CommonConstants.ONE_STRING.equals(sysBaseSetInfo.getBaseType())) {
			type = CommonConstants.TWO_INT;
		}
		// 记录变更日志
		tSocialLogService.saveModificationRecord(type, old.getId(), old, sysBaseSetInfo);
		return R.ok();
	}

	/**
	 * @param sysBaseSetInfo
	 * @Description: 新增、编辑社保、公积金基数
	 * @Author: hgw
	 * @Date: 2022/7/12 14:33
	 * @return: void
	 **/
	private void saveOrUpdateBaseAndFundPro(SysBaseSetInfo sysBaseSetInfo, SysBaseSetInfo old) {
		if (Common.isNotNull(sysBaseSetInfo.getId())) {
			baseMapper.updateById(sysBaseSetInfo);
		} else {
			sysBaseSetInfo.setStatus(CommonConstants.ZERO_INT);
			sysBaseSetInfo.setDeleteFlag(CommonConstants.ZERO_STRING);
			sysBaseSetInfo.setIsNew(CommonConstants.ONE_STRING);
			baseMapper.insert(sysBaseSetInfo);
			// 测试用（同步社保公积金查询、预估库），后面可删除
			//tForecastLibraryService.updateForecastLibaryBySysBase(sysBaseSetInfo)
		}
		List<SysPayProportion> payProportionList = sysBaseSetInfo.getFundProList();
		Map<String, SysPayProportion> oldFundMap = new HashMap<>();
		if (old != null && Common.isNotNull(old.getFundProList())) {
			for (SysPayProportion payProportion : old.getFundProList()) {
				oldFundMap.put(payProportion.getId(), payProportion);
			}
		}
		if (Common.isNotNull(payProportionList)) {
			for (SysPayProportion payProportion : payProportionList) {
				if (Common.isNotNull(payProportion.getId())) {
					sysPayProportionService.updateById(payProportion);
					oldFundMap.remove(payProportion.getId());
				} else {
					payProportion.setSysBaseSetId(sysBaseSetInfo.getId());
					sysPayProportionService.save(payProportion);
				}
			}
			for (SysPayProportion payProportion : payProportionList) {
				payProportion.setCreateBy(null);
				payProportion.setCreateName(null);
				payProportion.setCreateTime(null);
				payProportion.setUpdateBy(null);
				payProportion.setUpdateTime(null);
			}
			if (!oldFundMap.isEmpty()) {
				for (SysPayProportion fund : oldFundMap.values()) {
					sysPayProportionService.removeById(fund);
				}
			}
		}
	}

	@Override
	public Map<String, SysBaseSetInfo> getSysBaseSetInfoMap(String baseType) {
		// 基数配置
		SysBaseSetInfo sysBaseSetInfo = new SysBaseSetInfo();
		sysBaseSetInfo.setBaseType(baseType);
		sysBaseSetInfo.setDeleteFlag(CommonConstants.STATUS_NORMAL);
		sysBaseSetInfo.setStatus(CommonConstants.ZERO_INT);
		sysBaseSetInfo.setApplyStartDate(new Date());
		// 查询符合条件的基数列表
		List<SysBaseSetInfo> sysBaseSetInfoList = baseMapper.getSysBaseSetInfoNoPage(sysBaseSetInfo);
		// 返回的map
		Map<String, SysBaseSetInfo> setInfoMap = new HashMap<>();
		if (sysBaseSetInfoList != null && !sysBaseSetInfoList.isEmpty()) {
			// map的键
			String key;
			for (SysBaseSetInfo setInfo : sysBaseSetInfoList) {
				key = setInfo.getDepartId() + CommonConstants.DOWN_LINE_STRING + setInfo.getProvince()
						+ CommonConstants.DOWN_LINE_STRING + setInfo.getCity();
				if (setInfo.getTown() != null) {
					key += CommonConstants.DOWN_LINE_STRING + setInfo.getTown();
				}
				setInfoMap.put(key, setInfo);
			}
		}
		return setInfoMap;
	}

	@Override
	public R<Boolean> updateByIdAsso(String id ,int status) {
		SysBaseSetInfo baseSetInfo = baseMapper.selectById(id);
		if (null == baseSetInfo){
			return R.failed("无对应ID的数据！");
		}
		if (CommonConstants.ZERO_INT == status){
			SysHouseHoldInfo holdInfo = sysHouseHoldInfoMapper.selectById(baseSetInfo.getDepartId());
			if (Common.isNotNull(holdInfo) && CommonConstants.ONE_STRING.equals(holdInfo.getDelFlag())){
				return R.failed("对应户已禁用，禁止启用基数！");
			}
		}
		baseSetInfo.setStatus(status);
		int res = baseMapper.updateById(baseSetInfo);
		if (res >= 0){
			return R.ok();
		}else {
			return R.failed(CommonConstants.RESULT_DATA_FAIL);
		}
	}
}
