package com.example.demo.controller;

import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.example.demo.model.Payment;
import com.example.demo.model.PaymentMethod;
import com.example.demo.model.User;
import com.example.demo.service.AlipayService;
import com.example.demo.service.PaymentService;
import com.example.demo.service.UserService;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;

@Controller
@RequestMapping("/payment")
public class PaymentController {

    private static final Logger logger = LoggerFactory.getLogger(PaymentController.class);

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private UserService userService;
    
    /**
     * 显示支付页面
     */
    @GetMapping("/create")
    public String showPaymentForm(Model model) {
        model.addAttribute("payment", new Payment());
        model.addAttribute("paymentMethods", PaymentMethod.values());
        return "payment/form";
    }
    
    /**
     * 处理支付请求
     */
    @PostMapping("/create")
    public String createPayment(@Valid @ModelAttribute Payment payment, 
                               BindingResult result, 
                               Authentication authentication,
                               HttpServletRequest request,
                               Model model) {
        
        if (result.hasErrors()) {
            model.addAttribute("paymentMethods", PaymentMethod.values());
            return "payment/form";
        }
        
        try {
            // 设置当前用户
            String username = authentication.getName();
            User user = userService.findByUsername(username);
            payment.setUser(user);
            
            // 设置默认货币
            if (payment.getCurrency() == null || payment.getCurrency().isEmpty()) {
                payment.setCurrency("CNY");
            }
            
            // 获取客户端IP
            String clientIp = getClientIp(request);
            
            // 根据支付方式创建支付
            if (payment.getPaymentMethod() == PaymentMethod.ALIPAY) {
                Map<String, Object> paymentResult = alipayService.createPayment(payment, clientIp);
                if (paymentResult.containsKey("qrCode")) {
                    // 对于二维码支付，重定向到支付页面显示二维码
                    return "redirect:/payment/qr?qrCode=" + paymentResult.get("qrCode");
                }
                return "redirect:/payment/error";
            } else {
                model.addAttribute("error", "不支持的支付方式");
                model.addAttribute("paymentMethods", PaymentMethod.values());
                return "payment/form";
            }
            
        } catch (Exception e) {
            logger.error("创建支付订单失败：", e);
            model.addAttribute("error", "创建支付订单失败：" + e.getMessage());
            model.addAttribute("paymentMethods", PaymentMethod.values());
            return "payment/form";
        }
    }
    
    /**
     * 支付宝异步通知
     */
    @PostMapping("/alipay/notify")
    @ResponseBody
    public String alipayNotify(HttpServletRequest request) {
        logger.info("========== 收到支付宝回调请求 ==========");
        logger.info("请求方法: {}", request.getMethod());
        logger.info("请求URL: {}", request.getRequestURL());
        logger.info("Content-Type: {}", request.getContentType());
        try {
            // 支付宝异步通知参数获取
            // 注意：IJPay的AliPayApi.toMap()使用javax.servlet，但Spring Boot 3使用jakarta.servlet
            // 所以手动获取参数
            Map<String, String> params = new java.util.HashMap<>();
            
            // 获取URL参数
            request.getParameterMap().forEach((key, values) -> {
                if (values != null && values.length > 0) {
                    params.put(key, values[0]);
                }
            });
            
            // 如果是POST请求，尝试从请求体获取参数
            if ("POST".equalsIgnoreCase(request.getMethod())) {
                try {
                    // 读取请求体
                    StringBuilder body = new StringBuilder();
                    try (java.io.BufferedReader reader = request.getReader()) {
                        String line;
                        while ((line = reader.readLine()) != null) {
                            body.append(line);
                        }
                    }
                    
                    // 解析请求体参数（如果存在）
                    if (body.length() > 0) {
                        String bodyStr = body.toString();
                        // 支付宝可能使用form-urlencoded格式
                        if (bodyStr.contains("=")) {
                            String[] pairs = bodyStr.split("&");
                            for (String pair : pairs) {
                                String[] keyValue = pair.split("=", 2);
                                if (keyValue.length == 2) {
                                    try {
                                        params.put(
                                            java.net.URLDecoder.decode(keyValue[0], "UTF-8"),
                                            java.net.URLDecoder.decode(keyValue[1], "UTF-8")
                                        );
                                    } catch (Exception e) {
                                        logger.warn("解析参数失败: {}", pair, e);
                                    }
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    logger.warn("读取请求体失败", e);
                }
            }
            
            logger.info("解析到的参数: {}", params);
            boolean success = alipayService.handleNotify(params);
            logger.info("处理结果: {}", success ? "success" : "fail");
            logger.info("========== 支付宝回调处理完成 ==========");
            return success ? "success" : "fail";
            
        } catch (Exception e) {
            logger.error("========== 处理支付宝异步通知失败 ==========", e);
            return "fail";
        }
    }
    
    /**
     * 支付宝同步返回
     */
    @GetMapping("/alipay/return")
    public String alipayReturn(HttpServletRequest request, Model model) {
        try {
            // 支付宝同步返回参数获取（GET请求，从URL参数获取）
            Map<String, String> params = new java.util.HashMap<>();
            request.getParameterMap().forEach((key, values) -> {
                if (values != null && values.length > 0) {
                    params.put(key, values[0]);
                }
            });
            
            boolean success = alipayService.handleReturn(params);
            
            if (success) {
                String outTradeNo = params.get("out_trade_no");
                Payment payment = paymentService.findByOrderId(outTradeNo)
                    .orElseThrow(() -> new RuntimeException("支付记录不存在"));
                model.addAttribute("payment", payment);
                model.addAttribute("success", true);
                return "payment/result";
            } else {
                model.addAttribute("error", "支付验证失败");
                return "payment/result";
            }
            
        } catch (Exception e) {
            logger.error("处理支付宝同步返回失败：", e);
            model.addAttribute("error", "支付处理失败：" + e.getMessage());
            return "payment/result";
        }
    }
    
    /**
     * 支付记录列表
     */
    @GetMapping("/history")
    public String paymentHistory(Authentication authentication, Model model) {
        try {
            String username = authentication.getName();
            User user = userService.findByUsername(username);
            List<Payment> payments = paymentService.findByUserId(user.getId());
            model.addAttribute("payments", payments);
            return "payment/history";
        } catch (Exception e) {
            logger.error("获取支付记录失败：", e);
            model.addAttribute("error", "获取支付记录失败");
            return "payment/history";
        }
    }
    
    /**
     * 支付详情
     */
    @GetMapping("/detail/{id}")
    public String paymentDetail(@PathVariable Long id,
                              Authentication authentication,
                              Model model) {
        try {
            String username = authentication.getName();
            User user = userService.findByUsername(username);
            Payment payment = paymentService.findById(id)
                .orElseThrow(() -> new RuntimeException("支付记录不存在"));
            
            // 检查权限
            if (!payment.getUser().getId().equals(user.getId())) {
                model.addAttribute("error", "无权限访问此支付记录");
                return "payment/detail";
            }
            
            model.addAttribute("payment", payment);
            return "payment/detail";
            
        } catch (Exception e) {
            logger.error("获取支付详情失败：", e);
            model.addAttribute("error", "获取支付详情失败");
            return "payment/detail";
        }
    }
    
    /**
     * 获取客户端真实IP地址
     */
    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 如果是多个代理，取第一个IP
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }
        return ip;
    }
}
