package com.yifu.cloud.plus.v1.yifu.archives.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yifu.cloud.plus.v1.yifu.archives.entity.*;
import com.yifu.cloud.plus.v1.yifu.archives.service.*;
import com.yifu.cloud.plus.v1.yifu.archives.utils.NumberToCN;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.LocalDateTimeUtils;
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.dapr.config.DaprSalaryProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.HttpDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.log.annotation.SysLog;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.salary.vo.WageProofDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;


/**
 * @author pwang
 * @date 2019-11-05 15:24:25
 */
@RestController
@AllArgsConstructor
@RequestMapping("/salaryProve")
@Tag(name = "工资证明")
@Slf4j
@EnableConfigurationProperties(DaprSalaryProperties.class)
public class SalaryProveController {

	private final TProveApplyService tProveApplyService;
	private final TProveRecordService tProveRecordService;
	private final TEmployeeProjectService employeeProjectService;
	private final TEmployeeContractInfoService employeeContractInfoService;
	private final LUnitInfoForProveService unitInfoForProveService;
	private final TAttaInfoService attaInfoService;
	private final DaprSalaryProperties daprSalaryProperties;
	private static final String CREAT_DATE = "CREAT_DATE";//证明申请的申请时间

	/**
	 * 简单分页查询
	 *
	 * @param page        分页对象
	 * @param tProveApply
	 * @return
	 */
	@Operation(summary = "简单分页查询")
	@GetMapping("/page")
	public R<IPage<TProveApply>> getTProveApplyPage(Page<TProveApply> page, TProveApply tProveApply) {
		return new R<>(tProveApplyService.getTProveApplyPage(page, tProveApply));
	}


	/**
	 * 通过id查询单条记录
	 * @return R
	 */
	@Operation(summary = "id查询")
	@GetMapping("/{id}")
	public R<TProveApply> getById(@PathVariable("id") String id) {
		return new R<>(tProveApplyService.getById(id));
	}

	/**
	 * 新增记录
	 * @return R
	 */
	@Operation(summary = "新增(tproveapply_add)")
	@PostMapping
	@PreAuthorize("@pms.hasPermission('tproveapply_add')")
	public R<Boolean> save(@Valid @RequestBody TProveApply tProveApply) {
		return new R<>(tProveApplyService.save(tProveApply));
	}

	/**
	 * 修改记录
	 *
	 * @param tProveApply
	 * @return R
	 */
	@Operation(summary = "修改(tproveapply_edit)")
	@SysLog("修改")
	@PutMapping
	@PreAuthorize("@pms.hasPermission('tproveapply_edit')")
	public R<Boolean> update(@RequestBody TProveApply tProveApply) {
		return new R<>(tProveApplyService.updateById(tProveApply));
	}

	/**
	 * 通过id删除一条记录
	 *
	 * @param id
	 * @return R
	 */
	@Operation(summary = "删除(tproveapply_del)")
	@SysLog("删除")
	@DeleteMapping("/{id}")
	@PreAuthorize("@pms.hasPermission('tproveapply_del')")
	public R<Boolean> removeById(@PathVariable String id) {
		return new R<>(tProveApplyService.removeById(id));
	}

	/**
	 * 证明预览页面
	 *
	 * @param record
	 * @return
	 */
	@Operation(summary = "证明预览")
	@PostMapping(value = "/prove")
	public R<TProveRecord> prove(@RequestBody TProveRecord record) {
		String startDate;
		String endDate;
		String sumType;
		String emId;
		int count;
		String proveType;
		if (record != null) {
			startDate = record.getStartMonth();
			endDate = record.getEndMonth();
			sumType = record.getSumType();
			emId = record.getEmployeeInfo();
			proveType = record.getProveType();
		} else {
			return R.failed("参数错误！");
		}
		if (Common.isNotNull(startDate) && Common.isNotNull(endDate) && Common.isNotNull(sumType) && Common.isNotNull(emId) && Common.isNotNull(proveType)) {
			//员工信息
			TEmployeeProject em = employeeProjectService.getById(emId);
			if (null == em) {
				return R.failed("无此员工");
			}
			record.setEmployeeName(em.getEmpName());
			record.setEmployeeIdCard(em.getEmpIdcard());
			record.setEmployeeInfo(emId);
			record.setCreatDate(new Date());
			record.setEmployeeSettleDepartName(em.getDeptName());
			record.setPost(em.getPost());
			count = LocalDateTimeUtils.getBeginOfMonth(endDate.concat("01"), startDate.concat("01"), "yyyyMMdd") + 1;
			record.setMouthCount(count);
			if (CommonConstants.ZERO_STRING.equals(proveType)) {
				//正式员工证明
				//合同信息
				List<TEmployeeContractInfo> contractList = employeeContractInfoService.list(Wrappers.<TEmployeeContractInfo>lambdaQuery().eq(TEmployeeContractInfo::getEmpId, emId).eq(TEmployeeContractInfo::getIsObsolete, CommonConstants.ZERO_STRING).orderByDesc(TEmployeeContractInfo::getContractStart));
				if (Common.isNotNull(contractList)) {
					record.setContractEndDate(contractList.get(0).getContractEnd());
					record.setContractType(contractList.get(0).getContractType());
				}
			} else {
				//试用期证明
				record.setEntryDate(em.getEnjoinDate() == null ? em.getCreateTime().toLocalDate() : em.getEnjoinDate());
			}
			//申请信息
			LambdaQueryWrapper<TProveApply> eq = Wrappers.<TProveApply>lambdaQuery().eq(TProveApply::getEmployeeInfo, emId).eq(TProveApply::getAuditStatus, CommonConstants.dingleDigitStrArray[1])
					.eq(TProveApply::getSumType, sumType).eq(TProveApply::getStartMonth, startDate).eq(TProveApply::getEndMonth, endDate);
			List<TProveApply> list = tProveApplyService.list(eq);
			if (list != null && !list.isEmpty()) {//通过的申请
				BigDecimal salary = list.get(0).getProveSalary();
				record.setProveSalary(salary);
				record.setSalary(list.get(0).getSalary());
				record.setCapital(NumberToCN.number2CNMontrayUnit(salary));
			} else {
				try {
					WageProofDto pd = new WageProofDto();
					pd.setStartMouth(startDate);
					pd.setEndMouth(endDate);
					pd.setEmIdCard(record.getEmployeeIdCard());
					pd.setSumType(sumType);
					R<WageProofDto> wpR = HttpDaprUtil.invokeMethodPost(daprSalaryProperties.getAppUrl(), daprSalaryProperties.getAppId()
							, "/tsalaryaccount/inner/findAverageSalaryForProve", pd, WageProofDto.class, SecurityConstants.FROM_IN);
					if (null != wpR) {
						WageProofDto wp = wpR.getData();
						if (Common.isEmpty(wp.getErrorInfo())) {
							record.setProveSalary(wp.getSalary());
							record.setSalary(wp.getSalary());
							record.setCapital(NumberToCN.number2CNMontrayUnit(wp.getSalary()));
						} else {
							return R.failed(wp.getErrorInfo());
						}
					} else {
						return R.failed("调取工资服务返回数据出错！");
					}
				} catch (Exception e) {
					log.error("调取工资服务出错！", e);
					return R.failed("调取工资服务出错！");
				}
			}
		} else {
			return R.failed("参数出错！");
		}
		return R.ok(record);
	}

	/**
	 * 证明记录展示页面
	 */
	@Operation(summary = "证明记录展示页面")
	@GetMapping(value = "/printing/{id}")
	public R<TProveRecord> printing(@PathVariable String id) {
		TProveRecord re = tProveRecordService.getById(id);
		if (re != null) {
			re.setCapital(NumberToCN.number2CNMontrayUnit(re.getProveSalary()));
		} else {
			return R.failed("无此记录！");
		}
		return R.ok(re);
	}

	/**
	 * 打印次数加一
	 *
	 * @param id
	 */
	@Operation(summary = "打印次数加一")
	@GetMapping(value = "/addone/{id}")
	public R<String> addone(@PathVariable String id) {
		TProveRecord re = tProveRecordService.getById(id);
		if (null != re && null != re.getNumber()) {
			re.setNumber(re.getNumber() + 1);
			tProveRecordService.updateById(re);
			return R.ok("操作成功");
		} else {
			return R.failed("无此记录");
		}
	}

	/**
	 * 证明记录处理
	 */
	@Operation(summary = "证明记录处理")
	@PostMapping(value = "/proveRecord")
	public R<String> proveRecord(@Valid @RequestBody TProveRecord record) {
		YifuUser user = SecurityUtils.getUser();
		//记录用户单位信息
		String userId = String.valueOf(user.getId());
		if (!Common.isNotNull(record.getUnitAddr()) && !Common.isNotNull(record.getUnitName()) && !Common.isNotNull(record.getPhone())) {//有效数据
			try {
				LUnitInfoForProve unitInfo = new LUnitInfoForProve();
				unitInfo.setPhone(record.getPhone());
				unitInfo.setUnitAddr(record.getUnitAddr());
				unitInfo.setUnitName(record.getUnitName());
				unitInfo.setCreatUser(userId);
				if (null != record.getId()) {
					unitInfo.setId(record.getId());
					unitInfoForProveService.updateById(unitInfo);
				} else {
					//没有id检查数据有没有名称重复
					if (CommonConstants.dingleDigitIntArray[0] == unitInfoForProveService.count(Wrappers.<LUnitInfoForProve>lambdaQuery()
							.eq(LUnitInfoForProve::getCreatUser, userId).eq(LUnitInfoForProve::getUnitName, unitInfo.getUnitName()))) {
						unitInfoForProveService.save(unitInfo);
					}
				}
			} catch (Exception e) {
				log.error("用户操作数据保存出错", e);
			}
		}
		record.setId(null);
		if (CommonConstants.dingleDigitStrArray[0].equals(record.getProveType()) && Common.isEmpty(record.getPost())) {
			return R.failed("正式员工证明岗位不能为空！");
		}
		//处理证明记录
		record.setNumber(CommonConstants.dingleDigitIntArray[1]);
		record.setCreatUser(userId);
		record.setCreatUserName(user.getNickname());
		record.setIsInvalid(CommonConstants.ZERO_STRING);
		tProveRecordService.saveNo(record);//保存并自动生成编号
		return R.ok(record.getNo());
	}

	/**
	 * 证明记录分页
	 */
	@Operation(summary = "证明记录分页查询")
	@GetMapping("/findProveRecordPage")
	public R<IPage<TProveRecord>> findProveRecordPage(Page<TProveRecord> page, TProveRecord pr) {
		YifuUser user = SecurityUtils.getUser();
		if (user != null && Common.isNotNull(user.getId()) && CommonConstants.ONE_STRING.equals(user.getSystemFlag())) {
			pr.setCreatUser(String.valueOf(user.getId()));
		}
		page.addOrder(OrderItem.desc(CREAT_DATE));
		return new R<>(tProveRecordService.getTProveRecordPage(page, pr));
	}

	/**
	 * 修改作废状态
	 */
	@Operation(summary = "收入证明修改作废状态(tproveapply_invalid) status:是否作废(0否1是);invalidReason:作废理由")
	@SysLog("收入证明修改作废状态")
	@PostMapping(value = "/updateStatus")
	@PreAuthorize("@pms.hasPermission('tproveapply_invalid')")
	public R<String> updateStatus(String id, String status, String invalidReason) {
		if (id != null) {
			if (Common.isEmpty(status)) {
				return R.failed("作废状态不能为空！");
			}
			if (!CommonConstants.ZERO_STRING.equals(status) && invalidReason == null) {
				return R.failed("作废原因不能为空！");
			} else {
				TProveRecord pr = tProveRecordService.getById(id);
				if (pr != null) {
					pr.setIsInvalid(status);
					if (!CommonConstants.ZERO_STRING.equals(status)) {
						pr.setInvalidReason(invalidReason);
					}
					tProveRecordService.updateById(pr);
					return R.ok("操作成功！");
				} else {
					return R.failed("无此证明记录！");
				}
			}
		} else {
			return R.failed("id不能为空！");
		}
	}

	/**
	 * 证明记录
	 */
	@Operation(summary = "证明记录导出(tproveRecord_export接收流返回的文件，文件格式xls),idList:id 集合")
	@PostMapping(value = "/exportProveRecord")
	@PreAuthorize("@pms.hasPermission('tproveRecord_export')")
	public void exportProveRecord(HttpServletResponse response, @RequestBody TProveRecord pr) {
		YifuUser user = SecurityUtils.getUser();
		if (user != null && Common.isNotNull(user.getId()) && CommonConstants.ONE_STRING.equals(user.getSystemFlag())) {
			pr.setCreatUser(String.valueOf(user.getId()));
		}
		tProveRecordService.listExport(response, pr);
	}

	/**
	 * 新增证明申请
	 */
	@Operation(summary = "新增证明申请(tproveapply_apply)")
	@PostMapping(value = "/proveApply")
	@PreAuthorize("@pms.hasPermission('tproveapply_apply')")
	public R<String> proveApply(@Valid @RequestBody TProveApply proveApply, String[] attaIdArray) {
		TEmployeeProject em = employeeProjectService.getById(proveApply.getEmployeeInfo());
		if (null == em) {
			return R.failed("无此员工!");
		}
		proveApply.setEmployeeIdCard(em.getEmpIdcard());
		proveApply.setEmployeeName(em.getEmpName());
		proveApply.setSettleDomain(em.getDeptId());
		proveApply.setSettleDomainName(em.getDeptName());
		return tProveApplyService.validSave(proveApply, attaIdArray);
	}

	/**
	 * 证明申请审核分页
	 */
	@Operation(summary = "证明申请分页查询")
	@GetMapping("/proveApplyPage")
	public R<IPage<TProveApply>> findproveApplyPage(Page<TProveApply> page, TProveApply proveApply) {
		YifuUser user = SecurityUtils.getUser();
		if (user != null && Common.isNotNull(user.getId()) && CommonConstants.ONE_STRING.equals(user.getSystemFlag())) {
			proveApply.setCreatUser(String.valueOf(user.getId()));
		}
		if (Common.isEmpty(proveApply.getAuditStatus()) || !CommonConstants.dingleDigitStrArray[1].equals(proveApply.getAuditStatus())) {
			page.addOrder(OrderItem.desc(CREAT_DATE));
		}
		return new R<>(tProveApplyService.getTProveApplyPage(page, proveApply));
	}

	/**
	 * @Author pwang
	 * @Date 2019-11-08 14:32
	 **/
	@Operation(summary = "证明申请详情查询")
	@GetMapping("/lookApply/{id}")
	public R<TProveApply> lookApply(@PathVariable(value = "id", required = true) String id) {
		return R.ok(tProveApplyService.getById(id));
	}

	@Operation(summary = "证明申请附件查询")
	@GetMapping("/atta/{applyId}")
	public R<List<TAttaInfo>> lookApplyAtta(@PathVariable(value = "applyId") String applyId) {
		return attaInfoService.getAttaByApplyId(applyId);
	}

	/**
	 * 审核接口
	 */
	@Operation(summary = "审核接口(tproveapply_audit) auditStatus:审核结果(1审核通过2审核不通过)")
	@GetMapping("/updateApplyStatus")
	@PreAuthorize("@pms.hasPermission('tproveapply_audit')")
	public R<String> updateApplyStatus(@RequestParam String id, @RequestParam String auditStatus) {
		TProveApply pa = tProveApplyService.getById(id);
		if (pa != null) {
			if (!CommonConstants.dingleDigitStrArray[1].equals(auditStatus) && !CommonConstants.dingleDigitStrArray[2].equals(auditStatus)) {
				return R.failed("审核结果出错！");
			}
			YifuUser user = SecurityUtils.getUser();
			pa.setAuditUser(String.valueOf(user.getId()));
			pa.setAuditUserName(user.getNickname());
			pa.setAuditDate(LocalDate.now());
			pa.setAuditStatus(auditStatus);
			tProveApplyService.updateById(pa);
			return R.ok("操作成功！");
		} else {
			return R.failed("无此证明记录！");
		}
	}
}
