/*
 *    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.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.SysPayProportion;
import com.yifu.cloud.plus.v1.yifu.social.mapper.SysBaseSetInfoMapper;
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.TSocialLogService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * 基数设置表
 *
 * @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;

	/**
	 * 基数设置表简单分页查询
	 *
	 * @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
							.and(obj1 -> obj1
									.le(SysBaseSetInfo::getApplyStartDate, sysBaseSetInfo.getApplyStartDate())
									.and(obj2 -> obj2
											.ge(SysBaseSetInfo::getApplyEndDate, sysBaseSetInfo.getApplyStartDate())
											.or()
											.isNull(SysBaseSetInfo::getApplyEndDate)))
							.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
							.and(obj1 -> obj1
									.le(SysBaseSetInfo::getApplyStartDate, sysBaseSetInfo.getApplyStartDate())
									.and(obj2 -> obj2
											.ge(SysBaseSetInfo::getApplyEndDate, sysBaseSetInfo.getApplyStartDate())
											.or()
											.isNull(SysBaseSetInfo::getApplyEndDate)))
							.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
							.and(obj1 -> obj1
									.le(SysBaseSetInfo::getApplyStartDate, sysBaseSetInfo.getApplyStartDate())
									.and(obj2 -> obj2
											.ge(SysBaseSetInfo::getApplyEndDate, sysBaseSetInfo.getApplyStartDate())
											.or()
											.isNull(SysBaseSetInfo::getApplyEndDate)))
							.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(sysBaseSetInfo.getApplyStartDate());
			this.updateById(lastBase);
		}
		this.saveOrUpdateBaseAndFundPro(sysBaseSetInfo);
		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());
		}
		SysBaseSetInfo baseSetInfo = null;
		//	 where (b.apply_start_date < '2023-01' and ( b.apply_end_date > '2023-01' or b.apply_end_date is null) ) or b.apply_start_date > '2023-01'
		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())
					.ne(SysBaseSetInfo::getId, sysBaseSetInfo.getId())
					.eq(SysBaseSetInfo::getStatus, CommonConstants.ZERO_INT)
					.and(obj -> obj
							.and(obj1 -> obj1
									.le(SysBaseSetInfo::getApplyStartDate, sysBaseSetInfo.getApplyStartDate())
									.and(obj2 -> obj2
											.ge(SysBaseSetInfo::getApplyEndDate, sysBaseSetInfo.getApplyStartDate())
											.or()
											.isNull(SysBaseSetInfo::getApplyEndDate)))
							.or()
							.ge(SysBaseSetInfo::getApplyEndDate, sysBaseSetInfo.getApplyStartDate()))
					.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
							.and(obj1 -> obj1
									.le(SysBaseSetInfo::getApplyStartDate, sysBaseSetInfo.getApplyStartDate())
									.and(obj2 -> obj2
											.ge(SysBaseSetInfo::getApplyEndDate, sysBaseSetInfo.getApplyStartDate())
											.or()
											.isNull(SysBaseSetInfo::getApplyEndDate)))
							.or()
							.ge(SysBaseSetInfo::getApplyEndDate, sysBaseSetInfo.getApplyStartDate()))
					.ne(SysBaseSetInfo::getId, sysBaseSetInfo.getId())
					.eq(SysBaseSetInfo::getStatus, CommonConstants.ZERO_INT)
					.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
							.and(obj1 -> obj1
									.le(SysBaseSetInfo::getApplyStartDate, sysBaseSetInfo.getApplyStartDate())
									.and(obj2 -> obj2
											.ge(SysBaseSetInfo::getApplyEndDate, sysBaseSetInfo.getApplyStartDate())
											.or()
											.isNull(SysBaseSetInfo::getApplyEndDate)))
							.or()
							.ge(SysBaseSetInfo::getApplyEndDate, sysBaseSetInfo.getApplyStartDate()))
					.ne(SysBaseSetInfo::getId, sysBaseSetInfo.getId())
					.eq(SysBaseSetInfo::getStatus, CommonConstants.ZERO_INT)
					.last(CommonConstants.LAST_ONE_SQL));
		}
		if (null != baseSetInfo) {
			return R.failed("对应户、地市、有效期的基数配置已存在！");
		}

		this.saveOrUpdateBaseAndFundPro(sysBaseSetInfo);
		// 记录变更日志
		tSocialLogService.saveModificationRecord(CommonConstants.ONE_INT, 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) {
		if (Common.isNotNull(sysBaseSetInfo.getId())) {
			baseMapper.updateById(sysBaseSetInfo);
		} else {
			sysBaseSetInfo.setStatus(CommonConstants.ZERO_INT);
			sysBaseSetInfo.setDeleteFlag(CommonConstants.ZERO_STRING);
			baseMapper.insert(sysBaseSetInfo);
		}
		List<SysPayProportion> payProportionList = sysBaseSetInfo.getFundProList();
		if (Common.isNotNull(payProportionList)) {
			for (SysPayProportion payProportion : payProportionList) {
				if (Common.isNotNull(payProportion.getId())) {
					sysPayProportionService.updateById(payProportion);
				} else {
					payProportion.setSysBaseSetId(sysBaseSetInfo.getId());
					sysPayProportionService.save(payProportion);
				}
			}
		}
	}
}
