package com.nbport.zgwl.contractpush.service;

import cn.hutool.core.util.StrUtil;
import com.nbport.zgwl.contractpush.config.ContractPushProperties;
import com.nbport.zgwl.contractpush.dto.ApproveQueryRequestDTO;
import com.nbport.zgwl.contractpush.dto.ApproveViewUrlRequestDTO;
import com.nbport.zgwl.contractpush.dto.PushPayloadDTO;
import com.nbport.zgwl.contractpush.dto.PushTokenRequestDTO;
import com.nbport.zgwl.contractpush.handler.ContractPushRequestHandler;
import com.nbport.zgwl.contractpush.utils.ContractPushHttpUtils;
import com.nbport.zgwl.contractpush.utils.ContractPushUrlUtils;
import com.nbport.zgwl.exception.ServiceException;
import org.springframework.stereotype.Service;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 结算平台推送服务
 * 对应《结算平台推送合同接口文档V9.5》
 */
@Service
public class SettlementPushService {

    private final ContractPushProperties properties;
    private final ContractPushHttpUtils httpUtils;
    private final ContractPushRequestHandler requestHandler;

    public SettlementPushService(ContractPushProperties properties,
                                 ContractPushHttpUtils httpUtils,
                                 ContractPushRequestHandler requestHandler) {
        this.properties = properties;
        this.httpUtils = httpUtils;
        this.requestHandler = requestHandler;
    }

    /** 获取结算平台调用凭证 */
    public Map<String, Object> getToken(PushTokenRequestDTO requestDTO) {
        String systemKey = requestDTO != null && StrUtil.isNotBlank(requestDTO.getSystemKey())
                ? requestDTO.getSystemKey()
                : properties.getSettlement().getSystemKey();

        Map<String, String> query = new LinkedHashMap<>();
        query.put("systemKey", systemKey);
        return httpUtils.get(properties.getSettlement().getTokenUrl(), query);
    }

    /** 推送合同数据到结算平台 */
    public Map<String, Object> pushContract(PushPayloadDTO requestDTO) {
        String token = resolveSettlementToken(requestDTO == null ? null : requestDTO.getToken());
        Map<String, Object> body = requestHandler.prepareSettlementPayload(
                requestDTO == null ? null : requestDTO.getPayload(),
                token
        );
        return httpUtils.postJson(properties.getSettlement().getPushContractUrl(), body, null);
    }

    /** 查询合同审批记录 */
    public Map<String, Object> queryApproveInfo(ApproveQueryRequestDTO requestDTO) {
        Map<String, Object> body = new LinkedHashMap<>();
        body.put("token", resolveSettlementToken(requestDTO == null ? null : requestDTO.getToken()));
        body.put("phoneNum", requestDTO == null ? null : requestDTO.getPhoneNum());
        body.put("contractSysId", requestDTO == null ? null : requestDTO.getContractSysId());
        return httpUtils.postJson(properties.getSettlement().getApproveQueryUrl(), body, null);
    }

    /** 推送合同归档到结算平台 */
    public Map<String, Object> pushArchive(PushPayloadDTO requestDTO) {
        String token = resolveSettlementToken(requestDTO == null ? null : requestDTO.getToken());
        Map<String, Object> body = requestHandler.prepareSettlementPayload(
                requestDTO == null ? null : requestDTO.getPayload(),
                token
        );
        return httpUtils.postJson(properties.getSettlement().getArchiveUrl(), body, null);
    }

    /** 生成结算平台审批查看地址（单点登录） */
    public Map<String, Object> buildApproveViewUrl(ApproveViewUrlRequestDTO requestDTO) {
        if (requestDTO == null || StrUtil.isBlank(requestDTO.getContractId()) || StrUtil.isBlank(requestDTO.getIvUser())) {
            throw new ServiceException("contractId 和 ivUser 不能为空");
        }
        Map<String, Object> result = new LinkedHashMap<>();
        result.put(
                "approveViewUrl",
                ContractPushUrlUtils.buildApproveViewUrl(
                        properties.getSettlement().getApproveViewBaseUrl(),
                        requestDTO.getContractId(),
                        requestDTO.getIvUser()
                )
        );
        return result;
    }

    /** 获取结算平台 token，优先用入参，没有则自动调用 getToken 接口获取 */
    private String resolveSettlementToken(String inputToken) {
        if (StrUtil.isNotBlank(inputToken)) {
            return inputToken;
        }
        Map<String, Object> tokenResult = getToken(new PushTokenRequestDTO());
        Object data = tokenResult.get("data");
        if (data instanceof Map) {
            Object accessToken = ((Map<?, ?>) data).get("access_token");
            if (accessToken != null) {
                return String.valueOf(accessToken);
            }
        }
        throw new ServiceException("获取结算平台 token 失败");
    }
}
