package com.haha.miniapp.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson2.JSON;
import com.haha.common.vo.Result;
import com.haha.entity.Order;
import com.haha.service.OrderService;
import com.haha.service.payment.payscore.*;
import com.haha.service.payment.payscore.PayScoreCreateRequest.PostPayment;
import com.haha.service.payment.payscore.PayScoreCompleteRequest.PostDiscount;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.io.BufferedReader;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 微信支付分控制器
 * 提供支付分服务订单的创建、完结、取消、查询等 API
 */
@Slf4j
@RestController
@RequestMapping("/payscore")
@RequiredArgsConstructor
public class PayScoreController {

    private final PayScoreService payScoreService;
    private final OrderService orderService;

    /**
     * 创建支付分服务订单
     * POST /api/payscore/create
     *
     * @param params 请求参数
     *   - orderId: 订单ID（必填）
     *   - openId: 用户微信openId（必填）
     *   - riskFundAmount: 风险金额（可选，默认99元）
     *   - riskFundName: 风险金名称（可选，DEPOSIT/ADVANCE/CASH_DEPOSIT）
     * @return 支付分结果（含小程序调起支付分所需的package参数）
     */
    @PostMapping("/create")
    public Result<Map<String, Object>> createPayScoreOrder(@RequestBody Map<String, Object> params) {
        try {
            Long userId = StpUtil.getLoginIdAsLong();
            log.info("用户 {} 请求创建支付分服务订单", userId);

            if (!params.containsKey("orderId")) {
                return Result.error(400, "参数错误：orderId 不能为空");
            }
            if (!params.containsKey("openId")) {
                return Result.error(400, "参数错误：openId 不能为空");
            }

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

            Order order = orderService.getById(orderId);
            if (order == null) {
                return Result.error(404, "订单不存在");
            }
            if (!order.getUserId().equals(userId)) {
                return Result.error(403, "无权操作该订单");
            }

            BigDecimal riskFundAmount = null;
            if (params.containsKey("riskFundAmount")) {
                riskFundAmount = new BigDecimal(params.get("riskFundAmount").toString());
            }

            String riskFundName = null;
            if (params.containsKey("riskFundName")) {
                riskFundName = params.get("riskFundName").toString();
            }

            PayScoreResult result;
            if (riskFundAmount != null || riskFundName != null) {
                result = payScoreService.createPayScoreOrder(orderId, openId, riskFundAmount, riskFundName);
            } else {
                result = payScoreService.createPayScoreOrder(orderId, openId);
            }

            if (result.isSuccess()) {
                Map<String, Object> data = new HashMap<>();
                data.put("outOrderNo", result.getOutOrderNo());
                data.put("state", result.getState());
                data.put("package", result.getPackageStr());
                log.info("创建支付分服务订单成功 - orderId: {}, outOrderNo: {}", orderId, result.getOutOrderNo());
                return Result.success("创建成功", data);
            } else {
                log.warn("创建支付分服务订单失败 - orderId: {}, errorCode: {}, errorMsg: {}", 
                        orderId, result.getErrorCode(), result.getErrorMsg());
                return Result.error(500, result.getErrorMsg());
            }

        } catch (NumberFormatException e) {
            log.error("参数格式错误", e);
            return Result.error(400, "参数格式错误");
        } catch (Exception e) {
            log.error("创建支付分服务订单失败", e);
            return Result.error("创建失败：" + e.getMessage());
        }
    }

    /**
     * 完结支付分服务订单
     * POST /api/payscore/complete
     *
     * @param params 请求参数
     *   - orderId: 订单ID（必填）
     *   - totalAmount: 实际扣款总金额（必填）
     *   - payments: 后付费项目列表（可选）
     *   - discounts: 商户优惠列表（可选）
     * @return 支付分结果
     */
    @PostMapping("/complete")
    public Result<Map<String, Object>> completePayScoreOrder(@RequestBody Map<String, Object> params) {
        try {
            Long userId = StpUtil.getLoginIdAsLong();
            log.info("用户 {} 请求完结支付分服务订单", userId);

            if (!params.containsKey("orderId")) {
                return Result.error(400, "参数错误：orderId 不能为空");
            }
            if (!params.containsKey("totalAmount")) {
                return Result.error(400, "参数错误：totalAmount 不能为空");
            }

            Long orderId = Long.valueOf(params.get("orderId").toString());
            BigDecimal totalAmount = new BigDecimal(params.get("totalAmount").toString());

            Order order = orderService.getById(orderId);
            if (order == null) {
                return Result.error(404, "订单不存在");
            }
            if (!order.getUserId().equals(userId)) {
                return Result.error(403, "无权操作该订单");
            }

            List<PostPayment> payments = null;
            if (params.containsKey("payments")) {
                payments = JSON.parseArray(params.get("payments").toString(), PostPayment.class);
            }

            List<PostDiscount> discounts = null;
            if (params.containsKey("discounts")) {
                discounts = JSON.parseArray(params.get("discounts").toString(), PostDiscount.class);
            }

            PayScoreResult result = payScoreService.completePayScoreOrder(orderId, totalAmount, payments, discounts);

            if (result.isSuccess()) {
                Map<String, Object> data = new HashMap<>();
                data.put("outOrderNo", result.getOutOrderNo());
                data.put("state", result.getState());
                log.info("完结支付分服务订单成功 - orderId: {}, state: {}", orderId, result.getState());
                return Result.success("完结成功", data);
            } else {
                log.warn("完结支付分服务订单失败 - orderId: {}, errorCode: {}, errorMsg: {}", 
                        orderId, result.getErrorCode(), result.getErrorMsg());
                return Result.error(500, result.getErrorMsg());
            }

        } catch (NumberFormatException e) {
            log.error("参数格式错误", e);
            return Result.error(400, "参数格式错误");
        } catch (Exception e) {
            log.error("完结支付分服务订单失败", e);
            return Result.error("完结失败：" + e.getMessage());
        }
    }

    /**
     * 取消支付分服务订单
     * POST /api/payscore/cancel
     *
     * @param params 请求参数
     *   - orderId: 订单ID（必填）
     *   - reason: 取消原因（可选）
     * @return 支付分结果
     */
    @PostMapping("/cancel")
    public Result<Map<String, Object>> cancelPayScoreOrder(@RequestBody Map<String, Object> params) {
        try {
            Long userId = StpUtil.getLoginIdAsLong();
            log.info("用户 {} 请求取消支付分服务订单", userId);

            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() : "用户取消";

            Order order = orderService.getById(orderId);
            if (order == null) {
                return Result.error(404, "订单不存在");
            }
            if (!order.getUserId().equals(userId)) {
                return Result.error(403, "无权操作该订单");
            }

            PayScoreResult result = payScoreService.cancelPayScoreOrder(orderId, reason);

            if (result.isSuccess()) {
                Map<String, Object> data = new HashMap<>();
                data.put("outOrderNo", result.getOutOrderNo());
                data.put("state", result.getState());
                log.info("取消支付分服务订单成功 - orderId: {}", orderId);
                return Result.success("取消成功", data);
            } else {
                log.warn("取消支付分服务订单失败 - orderId: {}, errorCode: {}, errorMsg: {}", 
                        orderId, result.getErrorCode(), result.getErrorMsg());
                return Result.error(500, result.getErrorMsg());
            }

        } catch (NumberFormatException e) {
            log.error("参数格式错误", e);
            return Result.error(400, "参数格式错误");
        } catch (Exception e) {
            log.error("取消支付分服务订单失败", e);
            return Result.error("取消失败：" + e.getMessage());
        }
    }

    /**
     * 查询支付分服务订单状态
     * GET /api/payscore/query/{orderId}
     *
     * @param orderId 订单ID
     * @return 支付分订单状态
     */
    @GetMapping("/query/{orderId}")
    public Result<Map<String, Object>> queryPayScoreOrder(@PathVariable Long orderId) {
        try {
            Long userId = StpUtil.getLoginIdAsLong();
            log.info("用户 {} 查询支付分服务订单状态 - orderId: {}", userId, orderId);

            Order order = orderService.getById(orderId);
            if (order == null) {
                return Result.error(404, "订单不存在");
            }
            if (!order.getUserId().equals(userId)) {
                return Result.error(403, "无权访问该订单");
            }

            if (order.getPayScoreOrderId() == null) {
                return Result.error(400, "该订单未创建支付分服务订单");
            }

            PayScoreResult result = payScoreService.queryPayScoreOrder(order.getPayScoreOrderId());

            if (result.isSuccess()) {
                Map<String, Object> data = new HashMap<>();
                data.put("outOrderNo", result.getOutOrderNo());
                data.put("state", result.getState());
                data.put("totalAmount", result.getTotalAmount());
                log.info("查询支付分服务订单成功 - orderId: {}, state: {}", orderId, result.getState());
                return Result.success("查询成功", data);
            } else {
                log.warn("查询支付分服务订单失败 - orderId: {}, errorCode: {}, errorMsg: {}", 
                        orderId, result.getErrorCode(), result.getErrorMsg());
                return Result.error(500, result.getErrorMsg());
            }

        } catch (Exception e) {
            log.error("查询支付分服务订单失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }

    /**
     * 同步订单支付分状态
     * POST /api/payscore/sync/{orderId}
     *
     * @param orderId 订单ID
     * @return 操作结果
     */
    @PostMapping("/sync/{orderId}")
    public Result<Void> syncPayScoreStatus(@PathVariable Long orderId) {
        try {
            Long userId = StpUtil.getLoginIdAsLong();
            log.info("用户 {} 同步支付分状态 - orderId: {}", userId, orderId);

            Order order = orderService.getById(orderId);
            if (order == null) {
                return Result.error(404, "订单不存在");
            }
            if (!order.getUserId().equals(userId)) {
                return Result.error(403, "无权操作该订单");
            }

            boolean success = payScoreService.syncPayScoreStatus(orderId);

            if (success) {
                log.info("同步支付分状态成功 - orderId: {}", orderId);
                return Result.success("同步成功", null);
            } else {
                return Result.error(500, "同步失败");
            }

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

    /**
     * 支付分回调通知
     * POST /api/payscore/callback
     *
     * 注意：回调接口不需要 token 验证
     *
     * @param request HTTP请求
     * @return 回调响应
     */
    @SaIgnore
    @PostMapping("/callback")
    public String handleCallback(HttpServletRequest request) {
        try {
            log.info("收到支付分回调通知");

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

            Map<String, Object> params = new HashMap<>();
            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\": \"处理失败\"}";
            }

        } catch (Exception e) {
            log.error("处理支付分回调失败", e);
            return "{\"code\": \"FAIL\", \"message\": \"处理失败\"}";
        }
    }
}
