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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fadada.api.utils.crypt.FddCryptUtil;
import com.fasc.open.api.constants.RequestConstants;
import com.fasc.open.api.exception.ApiException;
import com.yifu.cloud.plus.v1.yifu.archives.config.FascConfig;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TFascPushLog;
import com.yifu.cloud.plus.v1.yifu.archives.service.FascService;
import com.yifu.cloud.plus.v1.yifu.archives.service.TFascPushLogService;
import com.yifu.cloud.plus.v1.yifu.archives.utils.DoFascTask;
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.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @auther huyc
 * @date 2022/6/29
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/fasc")
@Tag(name = "法大大专业版接口")
public class FascController {

	@Autowired
	private FascService fascService;
	@Autowired
	private FascConfig fascConfig;

	@Autowired
	@Lazy
	private DoFascTask doFascTask;

	private final TFascPushLogService tFascPushLogService;

	private static String FASC_EVENT = "X-FASC-Event";
	private static String FASC_BIZ_CONTENT = "bizContent";
	private static String FASC_SUCCESS = "success";

	/**
	 * @Description: 获取模板
	 * @Author: hgw
	 * @Date: 2025/9/26 16:21
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	@Operation(description = "每日定时获取法大大模板和详情")
	@PostMapping("/inner/everyDayGetFascTemplate")
	@Inner
	public R<String> everyDayGetFascTemplate() throws ApiException {
		return fascService.getTemplate(null);
	}

	/**
	 * @param templateName 签署任务模板名称，如果传了该参数，会根据名称模糊匹配查询，长度最大100个字符。
	 * @Description: 获取模板
	 * @Author: hgw
	 * @Date: 2025/9/26 16:21
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	@Operation(description = "获取模板")
	@GetMapping("/getTemplate")
	public R<String> getTemplate(@RequestParam(required = false) String templateName) throws ApiException {
		return fascService.getTemplate(templateName);
	}

	/**
	 * @param signTemplateId 签署任务模板ID
	 * @Description: 获取模板详情预览链接
	 * @Author: hgw
	 * @Date: 2025/9/26 16:21
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	@Operation(description = "获取模板详情预览链接")
	@GetMapping("/getTemplateDetailUrl")
	public R<String> getTemplateDetailUrl(@RequestParam String signTemplateId) throws ApiException {
		return fascService.getTemplateDetailUrl(signTemplateId);
	}

	/**
	 * @param id 合同待签订任务记录表TEmployeeContractPre：id
	 * @Description: 发起电子签署
	 * @Author: hgw
	 * @Date: 2025/10/13 17:24
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	@Operation(description = "发起电子签署")
	@GetMapping("/submitContract")
	public R<String> submitContract(@RequestParam String id) throws ApiException {
		return fascService.submitContract(id);
	}

	/**
	 * @param id 合同待签订任务记录表TEmployeeContractPre：id
	 * @Description: 撤销签署
	 * @Author: hgw
	 * @Date: 2025/10/13 17:24
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	@Operation(description = "撤销签署")
	@GetMapping("/cancelTask")
	public R<String> cancelTask(@RequestParam String id) throws ApiException {
		return fascService.cancelTask(id);
	}

	/**
	 * @param id 合同待签订任务记录表TEmployeeContractPre：id
	 * @Description: 催办
	 * @Author: hgw
	 * @Date: 2025/10/13 17:24
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	@Operation(description = "催办")
	@GetMapping("/urgeTask")
	public R<String> urgeTask(@RequestParam String id) throws ApiException {
		return fascService.urgeTask(id);
	}

	/**
	 * @param id 合同待签订任务记录表TEmployeeContractPre：id
	 * @Description: 获取附件
	 * @Author: hgw
	 * @Date: 2025/10/13 17:24
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	@Operation(description = "获取附件")
	@GetMapping("/getFileByRequestId")
	public R<String> getFileByRequestId(@RequestParam String id) throws ApiException {
		fascService.getFileByRequestId(id);
		return R.ok();
	}

	@Operation(summary = "异步通知", description = "异步通知")
	@RequestMapping(value = "/api/fascCallback")
	public R<String> notifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 新增推送日志
		TFascPushLog pushLog = new TFascPushLog();
		pushLog.setTransReferenceId(fascConfig.getOpenId());
		pushLog.setTaskStatus(CommonConstants.ONE_STRING);
		pushLog.setTypeKey("签署任务事件，异步通知");
		pushLog.setTypeName("签署任务事件，异步通知");
		tFascPushLogService.save(pushLog);

		if (checkSign(request, pushLog)) {
			pushLog.setTaskStatus(CommonConstants.TWO_STRING);
			tFascPushLogService.updateById(pushLog);
			return R.failed("验签失败");
		}
		tFascPushLogService.updateById(pushLog);
		String fddEvent = request.getHeader(FASC_EVENT);
		String fddBizContent = request.getParameter(FASC_BIZ_CONTENT);
		if (Common.isNotNull(fddEvent)) {
			JSONObject jsonObject = JSON.parseObject(fddBizContent);
			// 任务ID
			String signTaskId = jsonObject.getString("signTaskId");
			// 原因
			String terminationNote = jsonObject.getString("terminationNote");
			if (Common.isEmpty(terminationNote)) {
				terminationNote = jsonObject.getString("signRejectReason");
			}
			if (Common.isEmpty(terminationNote)) {
				terminationNote = jsonObject.getString("fillRejectReason");
			}
			if (Common.isEmpty(terminationNote)) {
				terminationNote = jsonObject.getString("signFailedReason");
			}
			// 操作人
			//String userName = jsonObject.getString("userName")

			// 异步执行：
			doFascTask.doFascOkCore(pushLog, fddEvent, fddBizContent, signTaskId, terminationNote);

			return R.ok(null, FASC_SUCCESS);
		}

		return R.ok(null, FASC_SUCCESS);
	}

	//验证签名，返回true表示失败
	public boolean checkSign(HttpServletRequest request, TFascPushLog pushLog) throws Exception {

		Map<String, String> paraMap = new HashMap<>();
		paraMap.put(RequestConstants.APP_ID, request.getHeader(RequestConstants.APP_ID));
		paraMap.put(RequestConstants.SIGN_TYPE, request.getHeader(RequestConstants.SIGN_TYPE));

		String timeStamp = request.getHeader(RequestConstants.TIMESTAMP);
		paraMap.put(RequestConstants.TIMESTAMP, timeStamp);
		paraMap.put(RequestConstants.NONCE, request.getHeader(RequestConstants.NONCE));
		paraMap.put(FASC_EVENT, request.getHeader(FASC_EVENT));
		paraMap.put(FASC_BIZ_CONTENT, request.getParameter(FASC_BIZ_CONTENT));
		//参数排序，ascii码排序
		String sortParam = FddCryptUtil.sortParameters(paraMap);
		pushLog.setPushData(sortParam);
		//计算之后得到签名 该签名需要放到请求头
		if (Common.isEmpty(sortParam) || Common.isEmpty(timeStamp)) {
			return true;
		}
		String signature = FddCryptUtil.sign(sortParam, timeStamp, fascConfig.getAppSecret());
		if (StringUtils.equals(signature, request.getHeader(RequestConstants.SIGN))) {
			return false;
		}
		// 表示验签失败：
		return true;
	}

}
