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.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
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.yeejoin.amos.boot.biz.common.controller.BaseController;
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.ContractDataDto;
import com.yeejoin.amos.boot.module.hygf.api.dto.HouseholdContractDto;
import com.yeejoin.amos.boot.module.hygf.api.entity.HouseholdContract;
import com.yeejoin.amos.boot.module.hygf.api.entity.SealDictionary;
import com.yeejoin.amos.boot.module.hygf.api.entity.ToDoTasks;
import com.yeejoin.amos.boot.module.hygf.api.entity.UserMessage;
import com.yeejoin.amos.boot.module.hygf.api.mapper.HouseholdContractMapper;
import com.yeejoin.amos.boot.module.hygf.api.mapper.SealDictionaryMapper;
import com.yeejoin.amos.boot.module.hygf.api.mapper.ToDoTasksMapper;
import com.yeejoin.amos.boot.module.hygf.api.mapper.UserMessageMapper;
import com.yeejoin.amos.boot.module.hygf.biz.service.impl.HouseholdContractServiceImpl;
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 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.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")
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;

    @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) {

        QueryWrapper<SealDictionary> queryWrapper=new QueryWrapper();
        queryWrapper.eq("amos_company_seq",sequenceNbr);
        SealDictionary sealDictionary=sealDictionaryMapper.selectOne(queryWrapper);
        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 = "post",value = "创建合同",   notes = "创建合同")
    @PostMapping (value = "/addContract")
    public ResponseModel<HouseholdContract> initiateHouseholdContract(@RequestBody HouseholdContractDto model) {
        HouseholdContract householdContract=householdContractServiceImpl.initiateHouseholdContract(model);
        return  ResponseHelper.buildResponse(householdContract);
    }



    @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);

          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);


              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);

              }
          }

        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("契约锁回调失败");
        }
        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 RuntimeException("解密失败");
        }
        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;


     }

}
