package com.nbport.zgwl.seal.service;

import com.alibaba.fastjson2.JSON;
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchDto;
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchLogDto;
import com.nbport.zgwl.contractlaunch.mapper.ContractLaunchMapper;
import com.nbport.zgwl.contractlaunch.utils.ContractLaunchConstants;
import com.nbport.zgwl.entity.SysUserEntity;
import com.nbport.zgwl.utils.AdminSecurityManage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * 签章操作日志服务
 *
 * 供 seal 包下的 Controller 使用，将签章平台的关键操作和回调
 * 统一写入合同操作日志表（SEAL_CONTRACT_LAUNCH_LOG），
 * 实现合同全生命周期的全程留痕。
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SealLogService {

    private final ContractLaunchMapper contractLaunchMapper;
    private final AdminSecurityManage adminSecurityManage;

    /**
     * 根据签章平台的 contractId 查找本系统的合同ID。
     *
     * 签章平台的 contractId 对应本系统合同的 sealContractId 字段。
     * 如果找不到对应的合同记录，返回 null。
     */
    public Long findContractIdBySealContractId(String sealContractId) {
        if (sealContractId == null || sealContractId.isBlank()) {
            return null;
        }
        try {
            ContractLaunchDto contract = contractLaunchMapper.selectContractBySealContractId(sealContractId);
            return contract == null ? null : contract.getId();
        } catch (Exception e) {
            log.warn("根据 sealContractId 查询合同失败: {}", sealContractId, e);
            return null;
        }
    }

    /**
     * 记录签章操作日志。
     *
     * @param contractId    本系统合同ID（可为 null，表示未关联到具体合同）
     * @param actionType    操作类型（见 ContractLaunchConstants.ACTION_SEAL_*）
     * @param actionName    操作名称
     * @param actionStatus  操作状态（success/failed/pending）
     * @param actionContent 操作内容描述
     * @param payload       原始报文（会被 JSON 序列化存储）
     */
    public void logSealAction(Long contractId, String actionType, String actionName,
                              String actionStatus, String actionContent, Object payload) {
        try {
            SysUserEntity currentUser = adminSecurityManage.getUser();
            ContractLaunchLogDto logDto = new ContractLaunchLogDto();
            logDto.setId(contractLaunchMapper.selectLogSeqNextVal());
            logDto.setContractId(contractId);
            logDto.setActionType(actionType);
            logDto.setActionName(actionName);
            logDto.setActionStatus(actionStatus);
            logDto.setOperatorName(currentUser == null ? "system" : currentUser.getUsername());
            logDto.setOperatorPhone(currentUser == null ? null : currentUser.getMobilePhone());
            logDto.setActionTime(LocalDateTime.now());
            logDto.setActionContent(actionContent);
            logDto.setCallbackPayload(payload == null ? null : JSON.toJSONString(payload));
            contractLaunchMapper.insertLog(logDto);
        } catch (Exception e) {
            // 日志记录失败不影响主流程
            log.error("写入签章操作日志失败 contractId={}, actionType={}", contractId, actionType, e);
        }
    }

    /**
     * 记录签章操作日志（简化版，自动使用 success 状态）。
     */
    public void logSealAction(Long contractId, String actionType, String actionName,
                              String actionContent, Object payload) {
        logSealAction(contractId, actionType, actionName,
                ContractLaunchConstants.ACTION_STATUS_SUCCESS, actionContent, payload);
    }
}
