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 org.springframework.web.multipart.MultipartFile;

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

/**
 * 数据采集推送服务
 * 对应《数据采集接口规范V3.0》
 */
@Service
public class DataCollectionPushService {

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

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

    /** 获取数据采集接口调用凭证（cj_token） */
    public Map<String, Object> getToken(PushTokenRequestDTO requestDTO) {
        String systemKey = requestDTO != null && StrUtil.isNotBlank(requestDTO.getSystemKey())
                ? requestDTO.getSystemKey()
                : properties.getDataCollection().getSystemKey();
        String secretKey = requestDTO != null && StrUtil.isNotBlank(requestDTO.getSecretKey())
                ? requestDTO.getSecretKey()
                : properties.getDataCollection().getSecretKey();

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

    /** 上传文件到法务系统（如合同附件、签订依据等） */
    public Map<String, Object> upload(MultipartFile file, String token) {
        Map<String, String> headers = requestHandler.buildDataCollectionHeaders(
                resolveCollectionToken(token),
                properties.getDataCollection().getSystemKey(),
                true
        );
        return httpUtils.postMultipart(properties.getDataCollection().getUploadUrl(), file, headers);
    }

    public Map<String, Object> upload(byte[] bytes, String originalFileName, String token) {
        Map<String, String> headers = requestHandler.buildDataCollectionHeaders(
                resolveCollectionToken(token),
                properties.getDataCollection().getSystemKey(),
                true
        );
        return httpUtils.postMultipart(properties.getDataCollection().getUploadUrl(), bytes, originalFileName, headers);
    }

    /** 相对方信息采集：将相对方信息推送给法务系统 */
    public Map<String, Object> collectOpposites(PushPayloadDTO requestDTO) {
        return postCollectionJson(properties.getDataCollection().getCollectOppositesUrl(), requestDTO, false);
    }

    /** 主体信息采集：将签约主体信息推送给法务系统 */
    public Map<String, Object> collectZtbs(PushPayloadDTO requestDTO) {
        return postCollectionJson(properties.getDataCollection().getCollectZtbsUrl(), requestDTO, false);
    }

    /** 合同信息采集：将合同数据推送给法务系统 */
    public Map<String, Object> collectContract(PushPayloadDTO requestDTO) {
        return postCollectionJson(properties.getDataCollection().getCollectContractUrl(), requestDTO, false);
    }

    /** 履行计划反馈：将合同收付款履行情况反馈给法务系统 */
    public Map<String, Object> collectPlanFeedback(PushPayloadDTO requestDTO) {
        return postCollectionJson(properties.getDataCollection().getCollectPlanFeedbackUrl(), requestDTO, false);
    }

    /** 合同完结：通知法务系统合同已完结 */
    public Map<String, Object> collectContractClose(PushPayloadDTO requestDTO) {
        return postCollectionJson(properties.getDataCollection().getCollectContractCloseUrl(), requestDTO, false);
    }

    /** 合同归档：签署版本文档推送给法务系统存档 */
    public Map<String, Object> collectContractArchive(PushPayloadDTO requestDTO) {
        return postCollectionJson(properties.getDataCollection().getCollectContractArchiveUrl(), requestDTO, false);
    }

    /** 查询合同审批信息 */
    public Map<String, Object> queryApproveInfo(ApproveQueryRequestDTO requestDTO) {
        Map<String, Object> body = new LinkedHashMap<>();
        body.put("contractCode", requestDTO == null ? null : requestDTO.getContractCode());
        body.put("contractId", requestDTO == null ? null : requestDTO.getContractId());
        body.put("phoneNum", requestDTO == null ? null : requestDTO.getPhoneNum());

        Map<String, String> headers = requestHandler.buildDataCollectionHeaders(
                resolveCollectionToken(requestDTO == null ? null : requestDTO.getToken()),
                properties.getDataCollection().getSystemKey(),
                true
        );
        Map<String, Object> requestBody = requestHandler.prepareDataCollectionPayload(
                body,
                properties.getDataCollection().getSysCode()
        );
        return httpUtils.postJson(properties.getDataCollection().getQueryApproveInfoUrl(), requestBody, headers);
    }

    /** 生成审批查看地址（单点登录跳转） */
    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.getDataCollection().getApproveViewBaseUrl(),
                        requestDTO.getContractId(),
                        requestDTO.getIvUser()
                )
        );
        return result;
    }

    /** 通用数据采集 POST 请求（拼装 headers + body 后发起调用） */
    private Map<String, Object> postCollectionJson(String url, PushPayloadDTO requestDTO, boolean includeSystemKeyHeader) {
        String token = resolveCollectionToken(requestDTO == null ? null : requestDTO.getToken());
        Map<String, String> headers = requestHandler.buildDataCollectionHeaders(
                token,
                properties.getDataCollection().getSystemKey(),
                includeSystemKeyHeader
        );
        Map<String, Object> requestBody = requestHandler.prepareDataCollectionPayload(
                requestDTO == null ? null : requestDTO.getPayload(),
                properties.getDataCollection().getSysCode()
        );
        return httpUtils.postJson(url, requestBody, headers);
    }

    /** 获取数据采集 token，优先用入参，没有则自动调用 getToken 接口获取 */
    private String resolveCollectionToken(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 失败");
    }
}
