package com.erp.platformsync.controller.pdd;

import com.erp.common.core.model.ApiResponse;
import com.erp.platformsync.dto.pdd.*;
import com.erp.platformsync.service.pdd.PddDeliveryService;
import com.erp.platformsync.service.pdd.PddOrderService;
import com.erp.platformsync.service.pdd.PddRefundService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 拼多多平台控制器
 * 实现拼多多开放平台API对接
 *
 * 路由对应:
 * - GET  /platform/status                    - 平台状态
 * - GET  /platform/pdd/authorize            - 拼多多授权URL
 * - GET  /platform/pdd/callback             - 拼多多回调
 * - GET  /platform/pdd/orders               - 订单列表
 * - GET  /platform/pdd/orders/{id}          - 订单详情
 * - POST /platform/pdd/delivery             - 拼多多发货
 * - GET  /platform/pdd/logistics            - 物流公司列表
 * - GET  /platform/pdd/goods               - 商品列表
 * - GET  /platform/pdd/goods/{id}          - 商品详情
 * - POST /platform/pdd/goods/stock         - 更新库存
 * - GET  /platform/pdd/refunds             - 退款列表
 * - POST /platform/pdd/refunds/{id}/agree  - 同意退款
 * - POST /platform/pdd/refunds/{id}/refuse - 拒绝退款
 * - POST /platform/pdd/waybill             - 申请运单
 * - GET  /platform/pdd/waybill/{code}/tracking - 运单轨迹
 */
@Slf4j
@RestController
@RequestMapping("/platform/pdd")
@RequiredArgsConstructor
public class PddController {

    private final PddOrderService pddOrderService;
    private final PddDeliveryService pddDeliveryService;
    private final PddRefundService pddRefundService;
    private final StringRedisTemplate redisTemplate;

    // 拼多多OAuth配置
    @Value("${erp.platform.pinduoduo.client-id:}")
    private String clientId;

    @Value("${erp.platform.pinduoduo.authorize-url:https://mms.pinduoduo.com/open.html}")
    private String authorizeUrl;

    @Value("${erp.platform.pinduoduo.callback-url:}")
    private String callbackUrl;

    // Redis key前缀
    private static final String REDIS_TOKEN_KEY = "erp:platform:pdd:token:";
    private static final String REDIS_AUTH_KEY = "erp:platform:pdd:auth:";

    // ==================== 平台状态 ====================

    /**
     * GET /platform/status
     * 获取平台状态
     */
    @GetMapping("/platform/status")
    public ApiResponse<Map<String, Object>> getPlatformStatus() {
        Map<String, Object> status = new HashMap<>();
        status.put("platform", "pinduoduo");
        status.put("name", "拼多多");
        status.put("configured", isConfigured());
        status.put("authorized", isAuthorized());
        status.put("timestamp", System.currentTimeMillis() / 1000);
        return ApiResponse.success(status);
    }

    // ==================== 授权相关 ====================

    /**
     * GET /platform/pdd/authorize
     * 获取拼多多授权URL
     */
    @GetMapping("/authorize")
    public ApiResponse<Map<String, String>> getAuthorizeUrl(
            @RequestParam(required = false) String state) {
        try {
            // 拼多多授权URL格式
            // https://mms.pinduoduo.com/open.html?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&state=STATE
            String redirectUri = callbackUrl != null && !callbackUrl.isEmpty()
                    ? callbackUrl
                    : "https://api.erpzbbh.cn/platform/pdd/callback";

            String authUrl = String.format("%s?response_type=code&client_id=%s&redirect_uri=%s&state=%s",
                    authorizeUrl,
                    clientId,
                    java.net.URLEncoder.encode(redirectUri, java.nio.charset.StandardCharsets.UTF_8),
                    state != null ? state : "pdd_auth");

            log.info("[pdd授权] 生成授权URL: clientId={}, redirectUri={}", clientId, redirectUri);

            Map<String, String> result = new HashMap<>();
            result.put("authorizeUrl", authUrl);
            result.put("state", state != null ? state : "pdd_auth");
            return ApiResponse.success(result);

        } catch (Exception e) {
            log.error("[pdd授权] 生成授权URL异常: {}", e.getMessage());
            return ApiResponse.error("生成授权URL失败: " + e.getMessage());
        }
    }

    /**
     * GET /platform/pdd/callback
     * 拼多多OAuth回调
     */
    @GetMapping("/callback")
    public ApiResponse<Map<String, Object>> callback(
            @RequestParam(required = false) String code,
            @RequestParam(required = false) String state,
            @RequestParam(required = false) String error,
            @RequestParam(required = false) String error_description) {

        log.info("[pdd回调] 收到回调: code={}, state={}, error={}", code, state, error);

        if (error != null) {
            log.error("[pdd回调] 授权失败: error={}, description={}", error, error_description);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("error", error);
            result.put("errorDescription", error_description);
            return ApiResponse.error("授权失败: " + error_description);
        }

        if (code == null || code.isEmpty()) {
            return ApiResponse.badRequest("授权码不能为空");
        }

        try {
            // 用code换取access_token（需要调用拼多多API）
            // 实际需要调用: https://gw-api.pinduoduo.com/api/router with type=pdd.auth.token.create
            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("code", code);
            result.put("state", state);

            // 保存授权状态到Redis
            String authKey = REDIS_AUTH_KEY + (state != null ? state : "default");
            redisTemplate.opsForValue().set(authKey, code, 30, TimeUnit.MINUTES);

            log.info("[pdd回调] 授权成功: code={}", code);
            return ApiResponse.success(result);

        } catch (Exception e) {
            log.error("[pdd回调] 处理回调异常: {}", e.getMessage());
            return ApiResponse.error("处理授权回调失败: " + e.getMessage());
        }
    }

    // ==================== 订单相关 ====================

    /**
     * GET /platform/pdd/orders
     * 获取订单列表
     */
    @GetMapping("/orders")
    public ApiResponse<List<PddOrderDTO>> getOrders(
            @RequestParam(required = false) Long shopId,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String startTime,
            @RequestParam(required = false) String endTime,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "20") Integer pageSize) {

        try {
            List<PddOrderDTO> orders = pddOrderService.getOrders(shopId, status, startTime, endTime, page, pageSize);
            return ApiResponse.success(orders);
        } catch (Exception e) {
            log.error("[pdd订单] 获取订单列表异常: {}", e.getMessage());
            return ApiResponse.error("获取订单列表失败: " + e.getMessage());
        }
    }

    /**
     * GET /platform/pdd/orders/{id}
     * 获取订单详情
     */
    @GetMapping("/orders/{id}")
    public ApiResponse<PddOrderDTO> getOrderDetail(@PathVariable("id") String orderId) {
        try {
            PddOrderDTO order = pddOrderService.getOrderDetail(orderId);
            if (order == null) {
                return ApiResponse.notFound("订单不存在: " + orderId);
            }
            return ApiResponse.success(order);
        } catch (Exception e) {
            log.error("[pdd订单] 获取订单详情异常: orderId={}, error={}", orderId, e.getMessage());
            return ApiResponse.error("获取订单详情失败: " + e.getMessage());
        }
    }

    // ==================== 发货相关 ====================

    /**
     * POST /platform/pdd/delivery
     * 拼多多发货
     */
    @PostMapping("/delivery")
    public ApiResponse<PddDeliveryDTO> deliver(@RequestBody PddDeliveryDTO request) {
        if (request.getOrderSn() == null || request.getOrderSn().isEmpty()) {
            return ApiResponse.badRequest("订单编号不能为空");
        }

        try {
            PddDeliveryDTO result = pddDeliveryService.deliver(
                    request.getOrderSn(),
                    request.getLogisticsCode(),
                    request.getWaybillNo(),
                    request.getRemark(),
                    request.getShopId()
            );
            if (result.getSuccess() != null && result.getSuccess()) {
                return ApiResponse.success("发货成功", result);
            } else {
                return ApiResponse.error(400, result.getErrorMsg(), result);
            }
        } catch (Exception e) {
            log.error("[pdd发货] 发货异常: orderSn={}, error={}", request.getOrderSn(), e.getMessage());
            return ApiResponse.error("发货失败: " + e.getMessage());
        }
    }

    /**
     * GET /platform/pdd/logistics
     * 获取物流公司列表
     */
    @GetMapping("/logistics")
    public ApiResponse<List<PddLogisticsDTO>> getLogisticsCompanies(
            @RequestParam(required = false) Long shopId) {
        try {
            List<PddLogisticsDTO> companies = pddDeliveryService.getLogisticsCompanies(shopId);
            return ApiResponse.success(companies);
        } catch (Exception e) {
            log.error("[pdd物流] 获取物流公司列表异常: {}", e.getMessage());
            return ApiResponse.error("获取物流公司列表失败: " + e.getMessage());
        }
    }

    // ==================== 商品相关 ====================

    /**
     * GET /platform/pdd/goods
     * 获取商品列表
     */
    @GetMapping("/goods")
    public ApiResponse<List<PddGoodsDTO>> getGoods(
            @RequestParam(required = false) Long shopId,
            @RequestParam(required = false) String goodsName,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "20") Integer pageSize) {

        try {
            List<PddGoodsDTO> goods = pddOrderService.getGoods(shopId, goodsName, page, pageSize);
            return ApiResponse.success(goods);
        } catch (Exception e) {
            log.error("[pdd商品] 获取商品列表异常: {}", e.getMessage());
            return ApiResponse.error("获取商品列表失败: " + e.getMessage());
        }
    }

    /**
     * GET /platform/pdd/goods/{id}
     * 获取商品详情
     */
    @GetMapping("/goods/{id}")
    public ApiResponse<PddGoodsDTO> getGoodsDetail(@PathVariable("id") Long goodsId) {
        try {
            PddGoodsDTO goods = pddOrderService.getGoodsDetail(goodsId);
            if (goods == null) {
                return ApiResponse.notFound("商品不存在: " + goodsId);
            }
            return ApiResponse.success(goods);
        } catch (Exception e) {
            log.error("[pdd商品] 获取商品详情异常: goodsId={}, error={}", goodsId, e.getMessage());
            return ApiResponse.error("获取商品详情失败: " + e.getMessage());
        }
    }

    /**
     * POST /platform/pdd/goods/stock
     * 更新商品库存
     */
    @PostMapping("/goods/stock")
    public ApiResponse<Map<String, Object>> updateStock(
            @RequestBody Map<String, Object> request) {

        Long skuId = request.get("skuId") != null ? Long.valueOf(request.get("skuId").toString()) : null;
        Integer stock = request.get("stock") != null ? Integer.valueOf(request.get("stock").toString()) : null;

        if (skuId == null || stock == null) {
            return ApiResponse.badRequest("skuId和stock不能为空");
        }

        try {
            log.info("[pdd商品] 更新库存: skuId={}, stock={}", skuId, stock);

            // 实际需要调用拼多多API: pdd.goods.stock.update
            Map<String, Object> result = new HashMap<>();
            result.put("skuId", skuId);
            result.put("stock", stock);
            result.put("success", true);
            return ApiResponse.success("库存更新成功", result);

        } catch (Exception e) {
            log.error("[pdd商品] 更新库存异常: skuId={}, error={}", skuId, e.getMessage());
            return ApiResponse.error("更新库存失败: " + e.getMessage());
        }
    }

    // ==================== 退款相关 ====================

    /**
     * GET /platform/pdd/refunds
     * 获取退款列表
     */
    @GetMapping("/refunds")
    public ApiResponse<List<PddRefundDTO>> getRefunds(
            @RequestParam(required = false) Long shopId,
            @RequestParam(required = false) Integer status,
            @RequestParam(required = false) String startTime,
            @RequestParam(required = false) String endTime,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "20") Integer pageSize) {

        try {
            List<PddRefundDTO> refunds = pddRefundService.getRefunds(shopId, status, startTime, endTime, page, pageSize);
            return ApiResponse.success(refunds);
        } catch (Exception e) {
            log.error("[pdd退款] 获取退款列表异常: {}", e.getMessage());
            return ApiResponse.error("获取退款列表失败: " + e.getMessage());
        }
    }

    /**
     * POST /platform/pdd/refunds/{id}/agree
     * 同意退款
     */
    @PostMapping("/refunds/{id}/agree")
    public ApiResponse<Map<String, Object>> agreeRefund(
            @PathVariable("id") String refundId,
            @RequestParam(required = false) String remark,
            @RequestParam(required = false) Long shopId) {

        try {
            boolean success = pddRefundService.agreeRefund(refundId, remark, shopId);

            Map<String, Object> result = new HashMap<>();
            result.put("refundId", refundId);
            result.put("success", success);

            if (success) {
                return ApiResponse.success("同意退款成功", result);
            } else {
                return ApiResponse.error(400, "同意退款失败", result);
            }
        } catch (Exception e) {
            log.error("[pdd退款] 同意退款异常: refundId={}, error={}", refundId, e.getMessage());
            return ApiResponse.error("同意退款失败: " + e.getMessage());
        }
    }

    /**
     * POST /platform/pdd/refunds/{id}/refuse
     * 拒绝退款
     */
    @PostMapping("/refunds/{id}/refuse")
    public ApiResponse<Map<String, Object>> refuseRefund(
            @PathVariable("id") String refundId,
            @RequestParam String reason,
            @RequestParam(required = false) Long shopId) {

        if (reason == null || reason.isEmpty()) {
            return ApiResponse.badRequest("拒绝原因不能为空");
        }

        try {
            boolean success = pddRefundService.refuseRefund(refundId, reason, shopId);

            Map<String, Object> result = new HashMap<>();
            result.put("refundId", refundId);
            result.put("reason", reason);
            result.put("success", success);

            if (success) {
                return ApiResponse.success("拒绝退款成功", result);
            } else {
                return ApiResponse.error(400, "拒绝退款失败", result);
            }
        } catch (Exception e) {
            log.error("[pdd退款] 拒绝退款异常: refundId={}, error={}", refundId, e.getMessage());
            return ApiResponse.error("拒绝退款失败: " + e.getMessage());
        }
    }

    // ==================== 运单相关 ====================

    /**
     * POST /platform/pdd/waybill
     * 申请运单
     */
    @PostMapping("/waybill")
    public ApiResponse<PddWaybillDTO> applyWaybill(@RequestBody PddWaybillDTO request) {
        if (request.getOrderSn() == null || request.getOrderSn().isEmpty()) {
            return ApiResponse.badRequest("订单编号不能为空");
        }

        try {
            PddWaybillDTO result = pddOrderService.applyWaybill(
                    request.getOrderSn(),
                    request.getLogisticsCode(),
                    request.getSenderName(),
                    request.getSenderPhone(),
                    request.getSenderAddress()
            );

            if (result.getSuccess() != null && result.getSuccess()) {
                return ApiResponse.success("申请运单成功", result);
            } else {
                return ApiResponse.error(400, result.getErrorMsg(), result);
            }
        } catch (Exception e) {
            log.error("[pdd运单] 申请运单异常: orderSn={}, error={}", request.getOrderSn(), e.getMessage());
            return ApiResponse.error("申请运单失败: " + e.getMessage());
        }
    }

    /**
     * GET /platform/pdd/waybill/{code}/tracking
     * 获取运单轨迹
     */
    @GetMapping("/waybill/{code}/tracking")
    public ApiResponse<Map<String, Object>> getWaybillTracking(@PathVariable("code") String waybillCode) {
        try {
            String tracking = pddOrderService.getWaybillTracking(waybillCode);

            Map<String, Object> result = new HashMap<>();
            result.put("waybillCode", waybillCode);
            result.put("tracking", tracking);

            return ApiResponse.success(result);
        } catch (Exception e) {
            log.error("[pdd运单] 获取运单轨迹异常: waybillCode={}, error={}", waybillCode, e.getMessage());
            return ApiResponse.error("获取运单轨迹失败: " + e.getMessage());
        }
    }

    // ==================== 辅助方法 ====================

    private boolean isConfigured() {
        return clientId != null && !clientId.isEmpty();
    }

    private boolean isAuthorized() {
        try {
            String token = redisTemplate.opsForValue().get(REDIS_TOKEN_KEY + "default");
            return token != null && !token.isEmpty();
        } catch (Exception e) {
            return false;
        }
    }
}
