package com.example.demo.controller;

import com.example.demo.model.Payment;
import com.example.demo.model.PaymentMethod;
import com.example.demo.model.PaymentStatus;
import com.example.demo.model.User;
import com.example.demo.service.AlipayService;
import com.example.demo.service.PayPalService;
import com.example.demo.service.PaymentService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
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.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@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 PayPalService payPalService;
    
    /**
     * 显示支付页面
     */
    @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,
                               Model model) {
        
        if (result.hasErrors()) {
            model.addAttribute("paymentMethods", PaymentMethod.values());
            return "payment/form";
        }
        
        try {
            // 设置当前用户
            User user = (User) authentication.getPrincipal();
            payment.setUser(user);
            
            // 设置默认货币
            if (payment.getCurrency() == null || payment.getCurrency().isEmpty()) {
                payment.setCurrency("CNY");
            }
            
            // 根据支付方式创建支付
            String redirectUrl;
            if (payment.getPaymentMethod() == PaymentMethod.ALIPAY) {
                redirectUrl = alipayService.createPayment(payment);
                return "redirect:" + redirectUrl;
            } else if (payment.getPaymentMethod() == PaymentMethod.PAYPAL) {
                redirectUrl = payPalService.createPayment(payment);
                return "redirect:" + redirectUrl;
            } 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) {
        try {
            Map<String, String> params = request.getParameterMap().entrySet().stream()
                .collect(java.util.stream.Collectors.toMap(
                    Map.Entry::getKey,
                    entry -> entry.getValue()[0]
                ));
            
            boolean success = alipayService.handleNotify(params);
            return success ? "success" : "fail";
            
        } catch (Exception e) {
            logger.error("处理支付宝异步通知失败：", e);
            return "fail";
        }
    }
    
    /**
     * 支付宝同步返回
     */
    @GetMapping("/alipay/return")
    public String alipayReturn(HttpServletRequest request, Model model) {
        try {
            Map<String, String> params = request.getParameterMap().entrySet().stream()
                .collect(java.util.stream.Collectors.toMap(
                    Map.Entry::getKey,
                    entry -> entry.getValue()[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";
        }
    }
    
    /**
     * PayPal支付返回
     */
    @GetMapping("/paypal/return")
    public String paypalReturn(@RequestParam("paymentId") String paymentId,
                             @RequestParam("PayerID") String payerId,
                             Model model) {
        try {
            boolean success = payPalService.executePayment(paymentId, payerId);
            
            if (success) {
                Payment payment = paymentService.findByExternalTransactionId(paymentId)
                    .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("处理PayPal支付返回失败：", e);
            model.addAttribute("error", "支付处理失败：" + e.getMessage());
            return "payment/result";
        }
    }
    
    /**
     * PayPal支付取消
     */
    @GetMapping("/paypal/cancel")
    public String paypalCancel(Model model) {
        model.addAttribute("error", "支付已取消");
        return "payment/result";
    }
    
    /**
     * PayPal Webhook通知
     */
    @PostMapping("/paypal/webhook")
    @ResponseBody
    public String paypalWebhook(HttpServletRequest request) {
        try {
            Map<String, String> params = request.getParameterMap().entrySet().stream()
                .collect(java.util.stream.Collectors.toMap(
                    Map.Entry::getKey,
                    entry -> entry.getValue()[0]
                ));
            
            boolean success = payPalService.handleWebhook(params);
            return success ? "success" : "fail";
            
        } catch (Exception e) {
            logger.error("处理PayPal Webhook失败：", e);
            return "fail";
        }
    }
    
    /**
     * 支付记录列表
     */
    @GetMapping("/history")
    public String paymentHistory(Authentication authentication, Model model) {
        try {
            User user = (User) authentication.getPrincipal();
            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 {
            User user = (User) authentication.getPrincipal();
            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";
        }
    }
}
