package com.haha.miniapp.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import com.alibaba.fastjson2.JSON;
import com.haha.common.enums.PaymentChannel;
import com.haha.common.vo.Result;
import com.haha.service.payment.PaymentCallbackResult;
import com.haha.service.payment.PaymentResult;
import com.haha.service.payment.PaymentService;
import com.haha.service.payment.RefundResult;
import com.haha.service.payment.payscore.PayScoreCallbackResult;
import com.haha.service.payment.payscore.PayScoreService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.BufferedReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 统一支付控制器
 * 提供统一的支付API，支持多渠道支付（微信、支付宝等）
 */
@Slf4j
@RestController
@RequestMapping("/api/payment")
public class PaymentController {

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private PayScoreService payScoreService;

    /**
     * 创建支付
     * POST /api/payment/create
     *
     * 请求参数:
     * - orderId: 订单ID（必填）
     * - channel: 支付渠道代码（必填，如 wechat/alipay/alipay_credit/balance）
     * - openId: 微信openId（微信支付必填）
     * - buyerId: 支付宝buyerId（支付宝支付必填）
     *
     * @param params 支付参数
     * @return 支付结果
     */
    @PostMapping("/create")
    public Result<PaymentResult> createPayment(@RequestBody Map<String, Object> params) {
        try {
            // 1. 提取参数
            if (!params.containsKey("orderId")) {
                return Result.error(400, "参数错误：orderId 不能为空");
            }
            if (!params.containsKey("channel")) {
                return Result.error(400, "参数错误：channel 不能为空");
            }

            Long orderId = Long.valueOf(params.get("orderId").toString());
            String channelCode = params.get("channel").toString();

            // 2. 转换 channel 字符串为 PaymentChannel 枚举
            PaymentChannel channel = PaymentChannel.fromCode(channelCode);
            if (channel == null) {
                return Result.error(400, "不支持的支付渠道: " + channelCode);
            }

            // 3. 构建 extra Map
            Map<String, String> extra = new HashMap<>();
            if (params.containsKey("openId")) {
                extra.put("openId", params.get("openId").toString());
            }
            if (params.containsKey("buyerId")) {
                extra.put("buyerId", params.get("buyerId").toString());
            }

            log.info("创建支付请求 - 订单ID: {}, 渠道: {}", orderId, channel.getDescription());

            // 4. 调用 paymentService.createPayment()
            PaymentResult result = paymentService.createPayment(orderId, channel, extra);

            // 5. 返回结果
            if (result.isSuccess()) {
                log.info("创建支付成功 - 订单ID: {}, 预支付ID: {}", orderId, result.getPrepayId());
                return Result.success("创建支付成功", result);
            } else {
                log.warn("创建支付失败 - 订单ID: {}, 错误: {}", orderId, result.getErrorMsg());
                return Result.error(500, result.getErrorMsg());
            }

        } catch (NumberFormatException e) {
            log.error("参数格式错误", e);
            return Result.error(400, "参数格式错误：orderId 必须为数字");
        } catch (Exception e) {
            log.error("创建支付失败", e);
            return Result.error("创建支付失败：" + e.getMessage());
        }
    }

    /**
     * 支付回调（按渠道路由）
     * POST /api/payment/callback/{channel}
     *
     * 注意：回调接口不需要 token 验证，使用 @SaIgnore
     *
     * @param channel       支付渠道代码
     * @param request       HTTP请求
     * @param requestParams 请求参数（form格式）
     * @return 回调响应
     */
    @SaIgnore
    @PostMapping("/callback/{channel}")
    public String handleCallback(
            @PathVariable String channel,
            HttpServletRequest request,
            @RequestParam(required = false) Map<String, String> requestParams) {
        try {
            log.info("收到支付回调 - 渠道: {}", channel);

            Map<String, Object> params = new HashMap<>();

            if ("wechat_payscore".equalsIgnoreCase(channel)) {
                StringBuilder sb = new StringBuilder();
                try (BufferedReader reader = request.getReader()) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        sb.append(line);
                    }
                }
                String body = sb.toString();

                params.put("body", body);
                params.put("Wechatpay-Timestamp", request.getHeader("Wechatpay-Timestamp"));
                params.put("Wechatpay-Nonce", request.getHeader("Wechatpay-Nonce"));
                params.put("Wechatpay-Signature", request.getHeader("Wechatpay-Signature"));
                params.put("Wechatpay-Serial", request.getHeader("Wechatpay-Serial"));
                params.put("Wechatpay-Signature-Type", request.getHeader("Wechatpay-Signature-Type"));

                log.info("微信支付分回调 - Timestamp: {}, Nonce: {}, Serial={}", 
                        params.get("Wechatpay-Timestamp"), 
                        params.get("Wechatpay-Nonce"), 
                        params.get("Wechatpay-Serial"));

                PayScoreCallbackResult result = payScoreService.handlePayScoreCallback(params);

                if (result.isSuccess()) {
                    log.info("支付分回调处理成功 - outOrderNo: {}, eventType: {}, state: {}", 
                            result.getOutOrderNo(), result.getEventType(), result.getState());
                    return "{\"code\": \"SUCCESS\", \"message\": \"成功\"}";
                } else {
                    log.warn("支付分回调处理失败 - errorMsg: {}", result.getErrorMsg());
                    return "{\"code\": \"FAIL\", \"message\": \"处理失败\"}";
                }
            }

            if ("wechat".equalsIgnoreCase(channel)) {
                StringBuilder sb = new StringBuilder();
                try (BufferedReader reader = request.getReader()) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        sb.append(line);
                    }
                }
                String body = sb.toString();
                
                params.put("body", body);
                params.put("Wechatpay-Timestamp", request.getHeader("Wechatpay-Timestamp"));
                params.put("Wechatpay-Nonce", request.getHeader("Wechatpay-Nonce"));
                params.put("Wechatpay-Signature", request.getHeader("Wechatpay-Signature"));
                params.put("Wechatpay-Serial", request.getHeader("Wechatpay-Serial"));
                params.put("Wechatpay-Signature-Type", request.getHeader("Wechatpay-Signature-Type"));
                
                if (body != null && !body.isEmpty()) {
                    try {
                        Map<String, Object> jsonParams = JSON.parseObject(body, Map.class);
                        params.putAll(jsonParams);
                    } catch (Exception ignored) {
                    }
                }
                log.info("微信V3回调 - Timestamp: {}, Nonce: {}, Serial: {}", 
                        params.get("Wechatpay-Timestamp"), 
                        params.get("Wechatpay-Nonce"), 
                        params.get("Wechatpay-Serial"));
            } else {
                params = parseRequestParams(request, requestParams);
            }
            log.info("支付回调参数: {}", JSON.toJSONString(params));

            PaymentChannel paymentChannel = PaymentChannel.fromCode(channel);
            if (paymentChannel == null) {
                log.warn("不支持的支付渠道: {}", channel);
                return buildCallbackErrorResponse(channel);
            }

            PaymentCallbackResult result = paymentService.handleCallback(paymentChannel, params);

            if (result.isSuccess()) {
                log.info("支付回调处理成功 - 订单号: {}, 交易号: {}", result.getOrderNo(), result.getTransactionId());
                return buildCallbackSuccessResponse(paymentChannel);
            } else {
                log.warn("支付回调处理失败 - 错误: {}", result.getErrorMsg());
                return buildCallbackErrorResponse(channel);
            }

        } catch (Exception e) {
            log.error("处理支付回调失败", e);
            return buildCallbackErrorResponse(channel);
        }
    }

    /**
     * 退款
     * POST /api/payment/refund
     *
     * 请求参数:
     * - orderId: 订单ID（必填）
     * - reason: 退款原因（可选）
     *
     * @param params 退款参数
     * @return 退款结果
     */
    @PostMapping("/refund")
    public Result<RefundResult> refund(@RequestBody Map<String, Object> params) {
        try {
            // 提取 orderId, reason
            if (!params.containsKey("orderId")) {
                return Result.error(400, "参数错误：orderId 不能为空");
            }

            Long orderId = Long.valueOf(params.get("orderId").toString());
            String reason = params.containsKey("reason") ? params.get("reason").toString() : "用户申请退款";

            log.info("退款请求 - 订单ID: {}, 原因: {}", orderId, reason);

            // 调用 paymentService.refund()
            RefundResult result = paymentService.refund(orderId, reason);

            if (result.isSuccess()) {
                log.info("退款成功 - 订单ID: {}, 退款单号: {}", orderId, result.getRefundId());
                return Result.success("退款成功", result);
            } else {
                log.warn("退款失败 - 订单ID: {}, 错误: {}", orderId, result.getErrorMsg());
                return Result.error(500, result.getErrorMsg());
            }

        } catch (NumberFormatException e) {
            log.error("参数格式错误", e);
            return Result.error(400, "参数格式错误：orderId 必须为数字");
        } catch (Exception e) {
            log.error("退款失败", e);
            return Result.error("退款失败：" + e.getMessage());
        }
    }

    /**
     * 获取可用支付渠道
     * GET /api/payment/channels
     *
     * @return 支付渠道列表
     */
    @GetMapping("/channels")
    public Result<List<Map<String, String>>> getChannels() {
        try {
            // 调用 paymentService.getAvailableChannels()
            List<PaymentChannel> channels = paymentService.getAvailableChannels();

            // 转换为 [{code: "wechat", name: "微信支付"}, ...] 格式
            List<Map<String, String>> channelList = channels.stream()
                    .map(channel -> {
                        Map<String, String> map = new HashMap<>();
                        map.put("code", channel.getCode());
                        map.put("name", channel.getDescription());
                        return map;
                    })
                    .collect(Collectors.toList());

            log.info("获取可用支付渠道 - 数量: {}", channelList.size());
            return Result.success("获取成功", channelList);

        } catch (Exception e) {
            log.error("获取支付渠道失败", e);
            return Result.error("获取支付渠道失败：" + e.getMessage());
        }
    }

    /**
     * 查询支付状态
     * GET /api/payment/query/{orderId}
     *
     * @param orderId 订单ID
     * @return 支付状态
     */
    @GetMapping("/query/{orderId}")
    public Result<PaymentResult> queryPayment(@PathVariable Long orderId) {
        try {
            log.info("查询支付状态 - 订单ID: {}", orderId);

            // 调用 paymentService.queryPaymentStatus()
            PaymentResult result = paymentService.queryPaymentStatus(orderId);

            if (result.isSuccess()) {
                return Result.success("查询成功", result);
            } else {
                return Result.error(500, result.getErrorMsg());
            }

        } catch (Exception e) {
            log.error("查询支付状态失败", e);
            return Result.error("查询支付状态失败：" + e.getMessage());
        }
    }

    /**
     * 解析请求参数，支持 JSON 和 form-urlencoded 两种格式
     *
     * @param request       HTTP请求对象
     * @param requestParams form表单参数
     * @return 参数Map
     */
    private Map<String, Object> parseRequestParams(HttpServletRequest request, Map<String, String> requestParams) {
        Map<String, Object> params = new HashMap<>();

        String contentType = request.getContentType();
        log.debug("请求Content-Type: {}", contentType);

        try {
            // 判断 Content-Type
            if (contentType != null && contentType.toLowerCase().contains("application/json")) {
                // JSON 格式：从 request body 读取
                StringBuilder sb = new StringBuilder();
                try (BufferedReader reader = request.getReader()) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        sb.append(line);
                    }
                }
                String body = sb.toString();
                if (body != null && !body.isEmpty()) {
                    params = JSON.parseObject(body, Map.class);
                    log.debug("解析JSON参数: {}", params.size());
                }
            } else if (contentType != null && contentType.toLowerCase().contains("text/xml")) {
                // XML 格式（微信支付回调）：从 request body 读取原始XML
                StringBuilder sb = new StringBuilder();
                try (BufferedReader reader = request.getReader()) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        sb.append(line);
                    }
                }
                String body = sb.toString();
                if (body != null && !body.isEmpty()) {
                    params.put("xmlBody", body);
                    log.debug("解析XML参数");
                }
            } else {
                // form-urlencoded 格式：使用 @RequestParam 捕获的参数
                if (requestParams != null && !requestParams.isEmpty()) {
                    params.putAll(requestParams);
                    log.debug("解析表单参数: {}", params.size());
                }
            }
        } catch (Exception e) {
            log.error("解析请求参数失败", e);
        }

        return params;
    }

    /**
     * 构建回调成功响应
     * 根据不同支付渠道返回不同格式的成功响应
     *
     * @param channel 支付渠道
     * @return 成功响应
     */
    private String buildCallbackSuccessResponse(PaymentChannel channel) {
        if (channel == PaymentChannel.WECHAT) {
            // 微信支付 V3 返回 JSON 格式
            return "{\"code\": \"SUCCESS\", \"message\": \"成功\"}";
        } else if (channel == PaymentChannel.ALIPAY || channel == PaymentChannel.ALIPAY_CREDIT) {
            // 支付宝返回 "success" 字符串
            return "success";
        } else {
            // 其他渠道默认返回 "success"
            return "success";
        }
    }

    /**
     * 构建回调失败响应
     *
     * @param channelCode 支付渠道代码
     * @return 失败响应
     */
    private String buildCallbackErrorResponse(String channelCode) {
        if ("wechat".equalsIgnoreCase(channelCode)) {
            // 微信支付 V3 返回 JSON 格式
            return "{\"code\": \"FAIL\", \"message\": \"处理失败\"}";
        } else {
            return "fail";
        }
    }
}
