package com.yeejoin.amos.boot.module.hygf.biz.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.qiyuesuo.sdk.v2.SdkClient;
import com.qiyuesuo.sdk.v2.bean.*;
import com.qiyuesuo.sdk.v2.exception.BaseSdkException;
import com.qiyuesuo.sdk.v2.json.JSONUtils;
import com.qiyuesuo.sdk.v2.request.*;
import com.qiyuesuo.sdk.v2.response.ContractListResult;
import com.qiyuesuo.sdk.v2.response.DocumentAddResult;
import com.qiyuesuo.sdk.v2.response.MiniappTicketResult;
import com.qiyuesuo.sdk.v2.response.SdkResponse;
import com.qiyuesuo.sdk.v2.utils.Algorithm;
import com.qiyuesuo.sdk.v2.utils.Base64Utils;
import com.qiyuesuo.sdk.v2.utils.CollectionUtils;
import com.yeejoin.amos.boot.biz.common.controller.BaseController;
import com.yeejoin.amos.boot.module.hygf.api.Enum.ArrivalStateeEnum;
import com.yeejoin.amos.boot.module.hygf.api.Enum.HouseholdContractEnum;
import com.yeejoin.amos.boot.module.hygf.api.Enum.TaskTypeStationEnum;
import com.yeejoin.amos.boot.module.hygf.api.dto.CallbackDto;
import com.yeejoin.amos.boot.module.hygf.api.dto.HouseholdContractDto;
import com.yeejoin.amos.boot.module.hygf.api.entity.*;
import com.yeejoin.amos.boot.module.hygf.api.mapper.*;
import com.yeejoin.amos.boot.module.hygf.biz.service.impl.HouseholdContractServiceImpl;
import com.yeejoin.amos.boot.module.hygf.biz.service.impl.PeasantHouseholdServiceImpl;
import com.yeejoin.amos.boot.module.hygf.biz.service.impl.QiyuesuoServiceImpl;
import com.yeejoin.amos.boot.module.hygf.biz.service.impl.ToDoTasksServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.typroject.tyboot.component.emq.EmqKeeper;
import org.typroject.tyboot.core.foundation.enumeration.UserType;
import org.typroject.tyboot.core.restful.doc.TycloudOperation;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseHelper;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @description:
 * @author: tw
 * @createDate: 2023/8/18
 */
@RestController
@Api(tags = "契税锁Api")
@RequestMapping(value = "/qiyuesuo")
@Slf4j
public class QiyuesuoController extends BaseController {
	private static final Logger logger = LoggerFactory.getLogger(QiyuesuoController.class);

	@Autowired
	SealDictionaryMapper sealDictionaryMapper;
	@Autowired
	QiyuesuoServiceImpl qiyuesuoService;
	@Autowired
	HouseholdContractServiceImpl householdContractServiceImpl;
	@Autowired
	HouseholdContractMapper householdContractMapper;
	@Autowired
	protected EmqKeeper emqKeeper;
	@Autowired
	UserMessageMapper userMessageMapper;
	@Autowired
	ToDoTasksMapper toDoTasksMapper;
	@Value("${qiyuesuo.secretKey}")
	private String secretKey;
	@Autowired
	ToDoTasksServiceImpl toDoTasksServiceImpl;
	@Value("${dealer.engineering}")
	private String engineering;
	@Autowired
	ContractFillMapper contractFillMapper;
	@Autowired
	PeasantHouseholdServiceImpl peasantHouseholdServiceImpl;
	@Autowired
	HygfContractCallRecordMapper hygfContractCallRecordMapper;

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(httpMethod = "POST", value = "个人token", notes = "个人token")
	@PostMapping(value = "/getUserToken")
	public ResponseModel<Object> getSdkResponse(@RequestBody UserAuthMiniappTicketRequest request) {
		SdkResponse<MiniappTicketResult> result = qiyuesuoService.getSdkResponse(request);
		return ResponseHelper.buildResponse(result.getResult());
	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(httpMethod = "POST", value = "合同token", notes = "合同token")
	@PostMapping(value = "/getContractToken")
	public ResponseModel<Object> getContractSdkResponse(@RequestBody ContractMiniappTicketRequest request) {
		SdkResponse<MiniappTicketResult> result = qiyuesuoService.getContractSdkResponse(request);
		return ResponseHelper.buildResponse(result.getResult());
	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(httpMethod = "POST", value = "合同token", notes = "合同token")
	@PostMapping(value = "/getContractTokengz/{sequenceNbr}")
	public ResponseModel<Object> getContractSdkResponseSequenceNbr(@RequestBody ContractMiniappTicketRequest request,
			@PathVariable(value = "sequenceNbr") Long sequenceNbr) {
		SealDictionary sealDictionary = sealDictionaryMapper.selectById(sequenceNbr);
		request.setUser(new User(sealDictionary.getSealedPhone(), "MOBILE"));
		SdkResponse<MiniappTicketResult> result = qiyuesuoService.getContractSdkResponse(request);
		return ResponseHelper.buildResponse(result.getResult());
	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(httpMethod = "GET", value = "获取所有盖章人员", notes = "获取所有盖章人员")
	@GetMapping(value = "/getAllUserByCompanySeq")
	public ResponseModel<List<SealDictionary>> getAll(@RequestParam(value = "companySeq") Long companySeq) {
		QueryWrapper<SealDictionary> queryWrapper = new QueryWrapper();
		queryWrapper.eq("amos_company_seq", companySeq);
		return ResponseHelper.buildResponse(sealDictionaryMapper.selectList(queryWrapper));
	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(httpMethod = "GET", value = "获取合同浏览令牌", notes = "获取合同浏览令牌")
	@GetMapping(value = "/getContractTokenTicket/{sequenceNbr}")
	public ResponseModel<Object> getContractTokenTicket(@PathVariable(value = "sequenceNbr") Long sequenceNbr) {
		SdkResponse<MiniappTicketResult> result = qiyuesuoService.getContractTokenTicket(sequenceNbr);
		return ResponseHelper.buildResponse(result.getResult());
	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(httpMethod = "POST", value = "创建合同", notes = "创建合同")
	@PostMapping(value = "/addContract")
	public ResponseModel<HouseholdContract> initiateHouseholdContract(@RequestBody HouseholdContractDto model) {
		HouseholdContract householdContract = new HouseholdContract();
		try {
			householdContract = householdContractServiceImpl.initiateHouseholdContract(model);
		} catch (Exception e) {
			log.error("创建合同错误, 入参: {}, error:", JSON.toJSONString(model), e);
			throw new BadRequest(e.getMessage());
		}
		return ResponseHelper.buildResponse(householdContract);
	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(httpMethod = "POST", value = "合同填充字段", notes = "合同填充字段")
	@GetMapping(value = "/getContractFill")
	public ResponseModel<List<ContractFill>> initiateHouseholdContract(Long templateId) {

		LambdaQueryWrapper<ContractFill> up = new LambdaQueryWrapper();
		up.eq(templateId != null, ContractFill::getTemplateId, templateId);
		List<ContractFill> list = contractFillMapper.selectList(up);
		return ResponseHelper.buildResponse(list);
	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(httpMethod = "POST", value = "契约锁回调接口", notes = "契约锁回调接口")
	@PostMapping(value = "/callback")
	public String callback(String content) {
		try {

			System.out.println("契约锁回调接口" + content);
			String data = this.aesDerypt(content, secretKey);
			System.out.println("契约锁回调接口解析数据" + data);
			CallbackDto CallbackDto = JSON.parseObject(data, CallbackDto.class);
			HygfContractCallRecord hygfContractCallRecord = new HygfContractCallRecord();
			try {
				hygfContractCallRecord.setContractId(CallbackDto.getContractId());
				hygfContractCallRecord.setRecDate(new Date());
				hygfContractCallRecord.setData(JSON.toJSONString(CallbackDto));
				hygfContractCallRecordMapper.insert(hygfContractCallRecord);
			}catch (Exception e){
				log.info("合同记录表保存失败，合同id"+CallbackDto.getContractId());
			}


			if ("PERSONAL".equals(CallbackDto.getCallbackType())) {

				LambdaUpdateWrapper<HouseholdContract> wrapper = new LambdaUpdateWrapper<>();
				wrapper.set(HouseholdContract::getSignStatus, HouseholdContractEnum.签字状态_已签字.getCode());
				wrapper.set(HouseholdContract::getStatus, HouseholdContractEnum.合同状态_农户已签署.getCode());
				wrapper.eq(HouseholdContract::getContractLockId, CallbackDto.getContractId());
				householdContractServiceImpl.update(wrapper);
				LambdaQueryWrapper<HouseholdContract> wrapper4 = new LambdaQueryWrapper<>();

				wrapper4.eq(HouseholdContract::getContractLockId, CallbackDto.getContractId());
				HouseholdContract householdContrac = householdContractMapper.selectOne(wrapper4);
				// 生成填报任务
				ToDoTasks toDoTasks1 = new ToDoTasks(TaskTypeStationEnum.合同填报.getCode(),
						householdContrac.getSequenceNbr(), "用户" + householdContrac.getPartyA() + "合同盖章", null);
				toDoTasksServiceImpl.addToDoTasksByRole(engineering, toDoTasks1, "合同签字成功");

			} else if ("SEAL".equals(CallbackDto.getCallbackType())) {

				LambdaUpdateWrapper<HouseholdContract> wrapper = new LambdaUpdateWrapper<>();
				wrapper.set(HouseholdContract::getStampStatus, HouseholdContractEnum.盖章状态_已盖章.getCode());
				wrapper.set(HouseholdContract::getSigningTime, new Date());
				wrapper.set(HouseholdContract::getStatus, HouseholdContractEnum.合同状态_双方已签署.getCode());
			//	wrapper.set(HouseholdContract::getSealedUser, getUserInfo().getRealName());
				wrapper.eq(HouseholdContract::getContractLockId, CallbackDto.getContractId());
				householdContractServiceImpl.update(wrapper);

				LambdaQueryWrapper<HouseholdContract> wrapper4 = new LambdaQueryWrapper<>();

				wrapper4.eq(HouseholdContract::getContractLockId, CallbackDto.getContractId());
				HouseholdContract contract = householdContractMapper.selectOne(wrapper4);
				PeasantHousehold peasantHousehold = peasantHouseholdServiceImpl.getDataByState(contract.getPeasantHouseholdId());
				logger.info("开始更新农户发货状态"+contract.getPeasantHouseholdId());
				if (peasantHousehold != null){
					logger.info("开始更新农户发货状态"+contract.getPeasantHouseholdId());
					peasantHousehold.setPreparationMoneyState(ArrivalStateeEnum.待发货.getCode());
					peasantHouseholdServiceImpl.getBaseMapper().updateById(peasantHousehold);
					logger.info("更新成功");
				}

				LambdaQueryWrapper<ToDoTasks> wrapper1 = new LambdaQueryWrapper<>();
				wrapper1.eq(ToDoTasks::getType, TaskTypeStationEnum.合同填报.getCode());
				wrapper1.eq(ToDoTasks::getState, "待办");
				wrapper1.eq(ToDoTasks::getBusinessId, contract.getSequenceNbr());
				ToDoTasks doTasks = toDoTasksMapper.selectOne(wrapper1);
				if (doTasks != null) {
					doTasks.setState("已办");
					doTasks.setCompleteTime(new Date());
					toDoTasksMapper.updateById(doTasks);
					emqKeeper.getMqttClient().publish("TASK_MESSAGE", JSON.toJSONString(doTasks).getBytes(), 2, false);

					UserMessage userMessage = new UserMessage(doTasks.getType(), doTasks.getBusinessId(),
							doTasks.getAmosUserId(), new Date(), doTasks.getTaskName() + "已完成",
							doTasks.getAmosOrgCode());
					userMessageMapper.insert(userMessage);
					emqKeeper.getMqttClient().publish("MY_MESSAGE", JSON.toJSONString(userMessage).getBytes(), 2,
							false);

				}
			}
			try {
				hygfContractCallRecord.setStatus("success");
				hygfContractCallRecordMapper.updateById(hygfContractCallRecord);
			}catch (Exception e){
				log.info("状态更新失败，合同id："+CallbackDto.getContractId());
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new BadRequest("契约锁回调失败");
		}
		return "success";
	}

	public String aesDerypt(String encrypt, String secret) {
		String decryptStr = null;
		try {
			byte[] decryptBytes = null;
			Cipher cipher = Cipher.getInstance(Algorithm.AES.getKey());
			byte[] bk = secret.getBytes("UTF-8");
			SecretKey secretKey = new SecretKeySpec(bk, Algorithm.AES.getKey());
			cipher.init(Cipher.DECRYPT_MODE, secretKey);
			byte[] scrBytes = Base64Utils.decode(encrypt);
			decryptBytes = cipher.doFinal(scrBytes);
			if (decryptBytes != null) {
				decryptStr = new String(decryptBytes, "UTF-8");
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new BadRequest("解密失败");
		}
		return decryptStr;
	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(httpMethod = "POST", value = "获取经销商单位", notes = "liebiao ")
	@PostMapping(value = "/getUnit1000")
	public ResponseModel<ContractListResult> getUnit1000(@RequestBody ContractListRequest request) {

		String serverUrl = "https://openapi.qiyuesuo.cn";
		String accessKey = "TdBmNkjAYd";
		String accessSecret = "y8KiDFKKDdC9Ld9Cm5zuy2rpXjxP5Z";
		SdkClient sdkClient = new SdkClient(serverUrl, accessKey, accessSecret);

		ContractListResult contractListResult = null;
		// 解析请求结果
		String response = sdkClient.service(request);
		SdkResponse<ContractListResult> qysResponse = JSONUtils.toQysResponse(response, ContractListResult.class);
		if (qysResponse.getCode() == 0) {
			contractListResult = qysResponse.getResult();
		} else {
			throw new BaseSdkException("请求失败，错误码:{}，错误信息:{}");
		}
		return ResponseHelper.buildResponse(qysResponse.getResult());
	}

	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@ApiOperation(httpMethod = "POST", value = "创建合同", notes = "创建合同")
	@PostMapping(value = "/getUnit2000")
	public ResponseModel<SdkResponse<Object>> getUnit2000(@RequestBody Map<String, String> map) {

		String username = map.get("username");
		String contact = map.get("contact");
		String IDCard = map.get("IDCard");
// 初始化sdkClient
		String serverUrl = "https://openapi.qiyuesuo.cn";
		String accessKey = "TdBmNkjAYd";
		String accessSecret = "y8KiDFKKDdC9Ld9Cm5zuy2rpXjxP5Z";
		SdkClient sdkClient = new SdkClient(serverUrl, accessKey, accessSecret);
// 合同基本参数

		// 进行日期格式化

		Contract contract = new Contract();
		contract.setSubject("户用光伏测试合同-" + username + new Date().getTime());
		contract.setDescription("户用光伏测试合同-" + username + new Date().getTime());
		contract.setExpireTime("2024-04-24 23:59:59");
		contract.setEndTime("2024-08-24 23:59:59");
		contract.setCategory(new Category("智信能源合同"));
		// contract.setBizId("");
		contract.setSend(false);
		// 个人
		Signatory signatory1 = new Signatory();
		signatory1.setTenantName(username);
		signatory1.setTenantType("PERSONAL");
		signatory1.setReceiver(new User(username, contact, "MOBILE"));
		signatory1.setSerialNo(1);

		// 对接方
		Signatory signatory2 = new Signatory();
		signatory2.setTenantName("智信能源科技有限公司-测试");
		signatory2.setTenantType("COMPANY");
		signatory2.setReceiver(new User("唐伟", "18291879708", "MOBILE"));
		signatory2.setSerialNo(2);
		Action action = new Action("COMPANY", 0);
		signatory2.addAction(action);
		// 设置签署方
		contract.addSignatory(signatory1);
		contract.addSignatory(signatory2);

		// 创建合同
		ContractDraftRequest request = new ContractDraftRequest(contract);
		String response = sdkClient.service(request);
		SdkResponse<Contract> responseObj = JSONUtils.toQysResponse(response, Contract.class);
		// 返回结果
		Contract result = new Contract();
		if (responseObj.getCode() == 0) {
			result = responseObj.getResult();
			logger.info(JSON.toJSONString(responseObj));
		} else {
			logger.info("请求失败，错误码:{}，错误信息:{}", responseObj.getCode(), responseObj.getMessage());
		}

		DocumentAddResult documentAddResult = this.getDocumentAddResult(result.getId(), username, contact, IDCard);
		List<Signatory> list = result.getSignatories();
		Long ActionId = null;
		Long SignatoryId = null;
		for (Signatory signatory : list) {
			if (signatory.getTenantType().equals("COMPANY")) {
				ActionId = signatory.getActions().get(0).getId();
			} else {
				SignatoryId = signatory.getId();
			}
		}

		SdkResponse<Object> data = this.getSdkResponse(result.getId(), ActionId, documentAddResult.getDocumentId(),
				SignatoryId);

		return ResponseHelper.buildResponse(data);

	}

	public DocumentAddResult getDocumentAddResult(Long contractId, String username, String contact, String IDCard) {
		// 初始化sdkClient
		String serverUrl = "https://openapi.qiyuesuo.cn";
		String accessKey = "TdBmNkjAYd";
		String accessSecret = "y8KiDFKKDdC9Ld9Cm5zuy2rpXjxP5Z";
		SdkClient sdkClient = new SdkClient(serverUrl, accessKey, accessSecret);
		// 添加合同文档
		List<TemplateParam> params = new ArrayList<>();
		params.add(new TemplateParam("name", username));
		params.add(new TemplateParam("IDCard", IDCard));

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		// 进行日期格式化
		String date = format.format(new Date());
		params.add(new TemplateParam("Date", date));

		DocumentAddByTemplateRequest request = new DocumentAddByTemplateRequest(contractId, 3130034494367662891L,
				params, "签署合同，");
		String response = sdkClient.service(request);
		SdkResponse<DocumentAddResult> responseObj = JSONUtils.toQysResponse(response, DocumentAddResult.class);
		DocumentAddResult result = null;
		if (responseObj.getCode() == 0) {
			result = responseObj.getResult();
			logger.info("添加合同文档成功，文档ID:{}", JSON.toJSONString(result));
		} else {
			logger.info("请求失败，错误码:{}，错误信息:{}", responseObj.getCode(), responseObj.getMessage());
		}

		return result;
	}

	public SdkResponse<Object> getSdkResponse(Long contractId, Long ActionId, Long documentId, Long SignatoryId) {

		String serverUrl = "https://openapi.qiyuesuo.cn";
		String accessKey = "TdBmNkjAYd";
		String accessSecret = "y8KiDFKKDdC9Ld9Cm5zuy2rpXjxP5Z";
		SdkClient sdkClient = new SdkClient(serverUrl, accessKey, accessSecret);
		// 发起时可以设置签署位置
		Stamper stamper = new Stamper();
		stamper.setActionId(ActionId);
		stamper.setDocumentId(documentId);
		stamper.setKeyword("单位名称");
		stamper.setType("COMPANY");
		stamper.setPage(1);
		stamper.setOffsetX(0.3);
		stamper.setOffsetY(0.0);

		Stamper stamper2 = new Stamper();
		stamper2.setSignatoryId(SignatoryId);
		stamper2.setDocumentId(documentId);
		stamper.setKeyword("签署方");
		stamper2.setType("PERSONAL");
		stamper2.setPage(1);
		stamper2.setOffsetX(0.0);
		stamper2.setOffsetY(0.0);
		List<Stamper> stampers = new ArrayList<>();
		stampers.add(stamper);
		stampers.add(stamper2);
// 发起合同
		SdkResponse<Object> responseObj = null;
		ContractSendRequest request = new ContractSendRequest(contractId, stampers);
		String response = sdkClient.service(request);
		responseObj = JSONUtils.toQysResponse(response);
		if (responseObj.getCode() == 0) {
			logger.info("合同发起成功");
		} else {
			logger.info("请求失败，错误码:{}，错误信息:{}", responseObj.getCode(), responseObj.getMessage());
		}

		return responseObj;

	}

}
