package com.erp.platformsync.adapter;

import com.erp.platformsync.dto.PullOrdersResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 通用平台适配器 - 支持配置化的平台API调用
 * 支持多平台：淘宝/天猫、京东、拼多多、抖音小店等
 *
 * 配置示例（application.yml）：
 * erp.platform:
 *   taobao:
 *     api-url: https://eco.taobao.com/router/rest
 *     app-key: xxx
 *     app-secret: xxx
 *     session-key: xxx
 *   jd:
 *     api-url: https://router.jd.com/api
 *     app-key: xxx
 *     app-secret: xxx
 *   pinduoduo:
 *     api-url: https://gw-api.pinduoduo.com/api/router
 *     client-id: xxx
 *     client-secret: xxx
 */
@Slf4j
public class GenericPlatformAdapter extends AbstractPlatformAdapter {

    private final String platformCode;
    private final String platformName;
    private final String apiUrl;
    private final String appKey;
    private final String appSecret;
    private final String accessToken;
    private final org.springframework.data.redis.core.StringRedisTemplate redisTemplate;

    private static final String REDIS_TOKEN_KEY = "erp:platform:generic:token";

    @Value("${erp.platform.generic.enabled:false}")
    private boolean enabled;

    public GenericPlatformAdapter(RestTemplate restTemplate,
                                  org.springframework.data.redis.core.StringRedisTemplate redisTemplate,
                                  @Value("${erp.platform.generic.code:}") String platformCode,
                                  @Value("${erp.platform.generic.name:}") String platformName,
                                  @Value("${erp.platform.generic.api-url:}") String apiUrl,
                                  @Value("${erp.platform.generic.app-key:}") String appKey,
                                  @Value("${erp.platform.generic.app-secret:}") String appSecret,
                                  @Value("${erp.platform.generic.access-token:}") String accessToken) {
        super(restTemplate);
        this.platformCode = platformCode;
        this.platformName = platformName;
        this.apiUrl = apiUrl;
        this.appKey = appKey;
        this.appSecret = appSecret;
        this.accessToken = accessToken;
        this.redisTemplate = redisTemplate;
    }

    @Override
    public String getPlatformCode() {
        return platformCode;
    }

    @Override
    public String getPlatformName() {
        return platformName;
    }

    @Override
    public boolean isConfigured() {
        return apiUrl != null && !apiUrl.isEmpty()
                && appKey != null && !appKey.isEmpty()
                && appSecret != null && !appSecret.isEmpty();
    }

    @Override
    protected String buildApiUrl(String path) {
        return apiUrl + path;
    }

    @Override
    protected String getAppSecret() {
        return appSecret;
    }

    @Override
    public List<PullOrdersResponse.PullOrderItem> pullOrders(Long shopId, String pullType,
                                                            String orderIds, LocalDateTime startTime,
                                                            LocalDateTime endTime) {
        if (!isConfigured()) {
            log.warn("[{}] 平台未配置，跳过拉取: apiUrl={}, appKey={}",
                    platformCode, apiUrl, appKey);
            return Collections.emptyList();
        }

        try {
            Map<String, Object> params = new HashMap<>();
            params.put("method", getPullOrdersMethod());
            params.put("app_key", appKey);
            params.put("timestamp", formatTime(LocalDateTime.now()));
            params.put("format", "json");
            params.put("v", "2.0");
            params.put("sign_method", "md5");
            params.put("shop_id", shopId);
            params.put("pull_type", pullType);
            if (orderIds != null) params.put("order_ids", orderIds);
            if (startTime != null) params.put("start_time", formatTime(startTime));
            if (endTime != null) params.put("end_time", formatTime(endTime));

            // 添加签名（简化版）
            params.put("sign", generateSign(params));

            PullOrdersResponse response = doGet("/orders/pull", PullOrdersResponse.class, params);
            if (response != null && response.getOrders() != null) {
                log.info("[{}] 拉取订单成功: count={}", platformCode, response.getOrders().size());
                return response.getOrders();
            }
            return Collections.emptyList();
        } catch (Exception e) {
            log.error("[{}] 拉取订单失败: shopId={}, error={}", platformCode, shopId, e.getMessage());
            return Collections.emptyList();
        }
    }

    @Override
    public boolean syncOrderToPlatform(String platformOrderSn, String syncStatus,
                                       String expressCompany, String expressNo) {
        if (!isConfigured()) {
            log.warn("[{}] 平台未配置，跳过同步: platformOrderSn={}", platformCode, platformOrderSn);
            return false;
        }

        try {
            Map<String, Object> body = new HashMap<>();
            body.put("method", getSyncOrderMethod());
            body.put("app_key", appKey);
            body.put("timestamp", formatTime(LocalDateTime.now()));
            body.put("format", "json");
            body.put("v", "2.0");
            body.put("sign_method", "md5");
            body.put("order_sn", platformOrderSn);
            body.put("status", syncStatus);
            if (expressCompany != null) body.put("express_company", expressCompany);
            if (expressNo != null) body.put("express_no", expressNo);

            body.put("sign", generateSign(body));

            Map<String, Object> response = doPost("/order/sync", body, Map.class);
            if (response != null) {
                log.info("[{}] 同步订单成功: platformOrderSn={}", platformCode, platformOrderSn);
                return true;
            }
            return false;
        } catch (Exception e) {
            log.error("[{}] 同步订单失败: platformOrderSn={}, error={}", platformCode, platformOrderSn, e.getMessage());
            return false;
        }
    }

    /**
     * 获取拉取订单的API方法名（子类重写）
     */
    protected String getPullOrdersMethod() {
        return "taobao.trades.sold.get";
    }

    /**
     * 获取同步订单状态的API方法名（子类重写）
     */
    protected String getSyncOrderMethod() {
        return "taobao.logistics.online.send";
    }

    /**
     * 生成签名（简化版MD5签名）
     */
    protected String generateSign(Map<String, Object> params) {
        // 按字典序排序参数
        List<String> keys = new ArrayList<>(params.keySet());
        Collections.sort(keys);

        StringBuilder sb = new StringBuilder(appSecret);
        for (String key : keys) {
            Object value = params.get(key);
            if (value != null && !value.toString().isEmpty()) {
                sb.append(key).append(value.toString());
            }
        }
        sb.append(appSecret);

        // 简化：使用 String.hashCode() 作为签名（实际项目应使用MD5）
        return Integer.toHexString(sb.toString().hashCode()).toUpperCase();
    }

    @Override
    protected void addAuthHeaders(HttpHeaders headers) {
        if (accessToken != null && !accessToken.isEmpty()) {
            headers.set("Authorization", "Bearer " + accessToken);
        }
    }
}
