package org.dromara.zhishu.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.api.Http;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.dromara.common.core.domain.R;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.system.service.ISysConfigService;
import org.dromara.system.service.impl.SysUserServiceImpl;
import org.dromara.zhishu.service.IShopService;
import org.dromara.zhishu.util.InterfaceUtils;
import org.dromara.zhishu.util.WxPayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.Base64;

@RestController
@RequestMapping("/xcx")
public class XcxController {

    @Autowired
    private IShopService shopService;

    // 微信小程序支付相关配置
    private static final String APPID = "wx703b8fb6c3da692a";
    private static final String MERCHANT_ID = "1524946931";
    private static final String NOTIFY_URL = "https://api.buzhiyushu.cn/weChat/wxPayCallBack";
    private final ISysConfigService configService;

    public XcxController(ISysConfigService configService) {
        this.configService = configService;
    }

    @GetMapping("/getShopId/{userId}")
    @SaIgnore
    public R<List<String>> getShopId(@PathVariable Long userId) {
        return R.ok(shopService.getShopId(userId));
    }

    /**
     * 小程序JSAPI支付统一下单
     */
    @SaIgnore
    @PostMapping("/jsapiPay")
    public R<Map<String, Object>> jsapiPay(@RequestBody Map<String, Object> requestData) {
        try {
            // 获取请求参数
            String openid = (String) requestData.get("openid");
            Long taskId = Long.valueOf(requestData.get("taskId").toString());
            Integer total = Integer.valueOf(requestData.get("total").toString());
            String totalStr = (String) requestData.get("totalStr");
            String description = (String) requestData.get("description");

            if (openid == null || openid.isEmpty()) {
                return R.fail("openid不能为空");
            }

            System.out.println("JSAPI支付请求参数: openid=" + openid + ", appid=" + APPID);

            // 生成订单号
            String outTradeNo = UUID.randomUUID().toString().replace("-", "");
            System.out.println("生成的订单号: " + outTradeNo);
            // 调用WxPayUtil的xcxPay方法，传入openid和订单号
            // 注意：需要修改WxPayUtil.xcxPay方法，添加outTradeNo参数
            String prepayId = WxPayUtil.xcxPay(taskId, total, totalStr, openid, APPID, outTradeNo);
            System.out.println("获取到的prepayId: " + prepayId);

            // 生成小程序调起支付的参数
            Map<String, Object> payParams = generatePayParams(prepayId);
            payParams.put("outTradeNo", outTradeNo);
            System.out.println("生成的支付参数: " + JsonUtils.toJsonString(payParams));

            // 直接返回支付参数，不要嵌套
            return R.ok(payParams);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("支付下单失败：" + e.getMessage());
        }
    }

    /**
     * 调用微信支付API
     */
    private String callWxPayApi(String path, Map<String, Object> requestData) throws Exception {
        String url = "https://api.mch.weixin.qq.com" + path;
        String requestBody = requestData != null ? JsonUtils.toJsonString(requestData) : "";

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost request = new HttpPost(url);
            request.setHeader("Content-Type", "application/json");
            request.setHeader("Accept", "application/json");

            // 添加微信支付签名
            String signature = WxPayUtil.generateSignature(requestBody, path);
            request.setHeader("Authorization", "WECHATPAY2-SHA256-RSA2048 " + signature);

            if (requestData != null) {
                StringEntity entity = new StringEntity(requestBody, "UTF-8");
                request.setEntity(entity);
            }

            try (CloseableHttpResponse response = httpClient.execute(request)) {
                HttpEntity responseEntity = response.getEntity();
                if (responseEntity != null) {
                    return EntityUtils.toString(responseEntity);
                }
            }
        }
        return null;
    }

    /**
     * 生成小程序调起支付的参数
     */
    private Map<String, Object> generatePayParams(String prepayId) throws Exception {
        // 构建请求参数
        String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
        // 生成随机字符串
        String nonceStr = UUID.randomUUID().toString().replace("-", "");
        // 构建package参数
        String packageStr = "prepay_id=" + prepayId;
        // 构建签名字符串
        String signString = APPID + "\n" + timeStamp + "\n" + nonceStr + "\n" + packageStr + "\n";
        String paySign = WxPayUtil.generatePaySign(signString);
        Map<String, Object> payParams = new HashMap<>();
        payParams.put("appId", APPID);
        payParams.put("timeStamp", timeStamp);
        payParams.put("nonceStr", nonceStr);
        payParams.put("package", packageStr);
        payParams.put("signType", "RSA");
        payParams.put("paySign", paySign);
        return payParams;
    }

    /**
     * 查询订单状态
     */
    @SaIgnore
    @PostMapping("/queryOrder")
    public R<Map<String, Object>> queryOrder(@RequestBody Map<String, Object> requestData) {
        try {
            String outTradeNo = (String) requestData.get("outTradeNo");
            if (outTradeNo == null || outTradeNo.isEmpty()) {
                return R.fail("订单号不能为空");
            }

            // 使用专门的GET请求方法调用微信API
            String path = "/v3/pay/transactions/out-trade-no/" + outTradeNo + "?mchid=" + MERCHANT_ID;
            String result = callWxPayApiGet(path);

            if (result == null || result.isEmpty()) {
                return R.fail("查询订单返回为空");
            }

            Map<String, Object> responseMap = JsonUtils.parseObject(result, Map.class);
            System.out.println("查询订单结果: " + result);
            return R.ok(responseMap);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("查询订单失败：" + e.getMessage());
        }
    }

    /**
     * 调用微信支付API (GET方法)
     */
    private String callWxPayApiGet(String path) throws Exception {
        String url = "https://api.mch.weixin.qq.com" + path;

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            org.apache.http.client.methods.HttpGet request = new org.apache.http.client.methods.HttpGet(url);
            request.setHeader("Content-Type", "application/json");
            request.setHeader("Accept", "application/json");

            // 生成时间戳和随机串
            String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
            String nonceStr = UUID.randomUUID().toString().replace("-", "");

            // 构建签名字符串 - GET请求的格式
            String signString = "GET\n" + path + "\n" + timestamp + "\n" + nonceStr + "\n\n";
            String signature = WxPayUtil.generatePaySign(signString);

            // 构建完整的认证头
            String token = "WECHATPAY2-SHA256-RSA2048 " +
                    "mchid=\"" + MERCHANT_ID + "\"," +
                    "nonce_str=\"" + nonceStr + "\"," +
                    "signature=\"" + signature + "\"," +
                    "timestamp=\"" + timestamp + "\"," +
                    "serial_no=\"1FD5B441796BE0250622018DF43EC4BAFB34FB78\"";

            request.setHeader("Authorization", token);

            System.out.println("查询订单URL: " + url);
            System.out.println("查询订单认证头: " + token);

            try (CloseableHttpResponse response = httpClient.execute(request)) {
                HttpEntity responseEntity = response.getEntity();
                if (responseEntity != null) {
                    return EntityUtils.toString(responseEntity);
                }
            }
        }
        return null;
    }

    /**
     * 关闭订单
     */
    @SaIgnore
    @PostMapping("/closeOrder")
    public R<String> closeOrder(@RequestBody Map<String, Object> requestData) {
        try {
            String outTradeNo = (String) requestData.get("outTradeNo");

            Map<String, Object> requestMap = new HashMap<>();
            requestMap.put("mchid", MERCHANT_ID);

            String path = "/v3/pay/transactions/out-trade-no/" + outTradeNo + "/close";
            String result = callWxPayApi(path, requestMap);

            return R.ok("订单关闭成功");
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("关闭订单失败：" + e.getMessage());
        }
    }

    /**
     * 申请退款
     */
    @SaIgnore
    @PostMapping("/refund")
    public R<Map<String, Object>> refund(@RequestBody Map<String, Object> requestData) {
        try {
            String outTradeNo = (String) requestData.get("outTradeNo");
            Integer total = Integer.valueOf(requestData.get("total").toString());
            Integer refund = Integer.valueOf(requestData.get("refund").toString());

            Map<String, Object> requestMap = new HashMap<>();
            requestMap.put("out_trade_no", outTradeNo);
            requestMap.put("out_refund_no", "refund_" + UUID.randomUUID().toString().replace("-", ""));

            // 设置金额信息
            Map<String, Object> amount = new HashMap<>();
            amount.put("refund", refund);
            amount.put("total", total);
            amount.put("currency", "CNY");
            requestMap.put("amount", amount);

            String path = "/v3/refund/domestic/refunds";
            String result = callWxPayApi(path, requestMap);
            Map<String, Object> responseMap = JsonUtils.parseObject(result, Map.class);

            return R.ok(responseMap);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("申请退款失败：" + e.getMessage());
        }
    }

    /**
     * 查询退款状态
     */
    @SaIgnore
    @GetMapping("/queryRefund")
    public R<Map<String, Object>> queryRefund(@RequestParam String outRefundNo) {
        try {
            String path = "/v3/refund/domestic/refunds/" + outRefundNo;
            String result = callWxPayApi(path, null);
            Map<String, Object> responseMap = JsonUtils.parseObject(result, Map.class);

            return R.ok(responseMap);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("查询退款失败：" + e.getMessage());
        }
    }

    /**
     * 微信支付回调接口
     */
    @SaIgnore
    @PostMapping("/wxPayCallBack")
    public String wxPayCallBack(HttpServletRequest request, HttpServletResponse response) {
        try {
            // 获取请求头和请求体
            Map<String, String> headers = WxPayUtil.getHeaders(request);
            String requestBody = WxPayUtil.getRequestBody(request);

            // 记录回调信息
            System.out.println("接收到微信支付回调: " + requestBody);

            // 获取签名相关信息
            String timestamp = headers.get("wechatpay-timestamp");
            String nonce = headers.get("wechatpay-nonce");
            String signature = headers.get("wechatpay-signature");
            String serialNo = headers.get("wechatpay-serial");

            // 验证签名
            // 这里需要根据证书序列号获取对应的公钥
            // PublicKey publicKey = ... 获取公钥的逻辑

            // 解析请求体
            Map<String, Object> bodyMap = JsonUtils.parseObject(requestBody, Map.class);
            Map<String, Object> resourceMap = (Map<String, Object>) bodyMap.get("resource");

            // 获取加密数据
            String ciphertext = (String) resourceMap.get("ciphertext");
            String nonce64 = (String) resourceMap.get("nonce");
            String associatedData = (String) resourceMap.get("associated_data");

            // 解密数据
            String decryptedData = WxPayUtil.decryptToString(
                    associatedData != null ? associatedData.getBytes() : new byte[0],
                    Base64.getDecoder().decode(nonce64),
                    ciphertext,
                    WxPayUtil.getApiV3Key().getBytes()
            );

            // 解析解密后的数据
            Map<String, Object> decryptedMap = JsonUtils.parseObject(decryptedData, Map.class);

            // 获取商户订单号和交易状态
            String outTradeNo = (String) decryptedMap.get("out_trade_no");
            String tradeState = (String) decryptedMap.get("trade_state");
            String transactionId = (String) decryptedMap.get("transaction_id");
            String attach = (String) decryptedMap.get("attach");

            // 处理支付结果
            if ("SUCCESS".equals(tradeState)) {
                // 支付成功，更新订单状态
                // 这里可以调用订单服务更新状态
                Long taskId = Long.valueOf(attach);
                System.out.println("支付成功，taskId: " + taskId + ", 订单号: " + outTradeNo);
                // TODO: 处理业务逻辑，例如更新订单状态
            }

            // 返回成功
            Map<String, String> result = new HashMap<>();
            result.put("code", "SUCCESS");
            result.put("message", "成功");
            return JsonUtils.toJsonString(result);
        } catch (Exception e) {
            e.printStackTrace();
            // 返回失败
            Map<String, String> result = new HashMap<>();
            result.put("code", "FAIL");
            result.put("message", e.getMessage());
            return JsonUtils.toJsonString(result);
        }
    }

    // 查询用户是否为小程序孔网翻新会员
    @SaIgnore
    @GetMapping("/queryUserIsKwfwMember")
    public R<Map<String, Object>> queryUserIsKwfwMember(@RequestParam String userId) {
        try {
            long userIdLong = Long.parseLong(userId);
            Map<String, Object> params = new HashMap<>();
            params.put("userId", userIdLong); // 保持小写 u
            params.put("type", 3);            // 小写 t
            params.put("payStatus", 0);       // 小写 p

            // 调用外部接口
            String path = "/user/checkPaymentRecord";
            String goUrl = configService.selectConfigByKey("go.url");
//            String goUrl = "http://localhost:9004/api";
            String responseStr = InterfaceUtils.getInterfacePost(goUrl, path, params);

            // 解析响应JSON
            Map<String, Object> responseMap = JsonUtils.parseObject(responseStr, Map.class);
            if (responseMap == null) {
                Map<String, Object> errorResult = new HashMap<>();
                errorResult.put("isMember", false);
                return R.fail("响应数据解析失败", errorResult);
            }

            // 检查响应状态码
            Integer code = (Integer) responseMap.get("code");
            if (code == null || code != 200) {
                String msg = (String) responseMap.get("msg");
                Map<String, Object> errorResult = new HashMap<>();
                errorResult.put("isMember", false);
                return R.fail("接口调用失败: " + (msg != null ? msg : "未知错误"), errorResult);
            }

            // 提取data字段的值
            Boolean isMember = (Boolean) responseMap.get("data");
            Map<String, Object> result = new HashMap<>();
            result.put("isMember", isMember != null ? isMember : false);

            return R.ok("查询成功", result);

        } catch (Exception e) {
            // 异常处理
            Map<String, Object> errorResult = new HashMap<>();
            errorResult.put("isMember", false);
            return R.fail("查询失败: " + e.getMessage(), errorResult);
        }
    }

    /**
     * 扫码获取在售/已售商品
     * 
     * @param keyword 搜索关键词（ISBN）
     * @param dataType 数据类型，0表示在售商品，1表示已售商品
     * @param cookie 请求Cookie信息
     * @return 商品信息结果
     */
    @SaIgnore
    @GetMapping("/getOnSaleGoods")
    public R<Map<String, Object>> getOnSaleGoods(@RequestParam String keyword,
                                                 @RequestParam(defaultValue = "0") int dataType,
                                                 @RequestParam String cookie) {
        try {
            // 构建请求URL
            String baseUrl = "https://search.kongfz.com/pc-gw/search-web/client/pc/product/keyword/list";
            
            // 构建请求参数
            UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(baseUrl)
                .queryParam("dataType", dataType)
                .queryParam("keyword", keyword)
//                .queryParam("page", 1)
                .queryParam("userArea", "13003000000");
            
            // 创建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.set("Accept", "application/json, text/plain, */*");
            headers.set("Accept-Language", "zh-CN,zh;q=0.9");
            headers.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36");
            headers.set("Referer", "https://search.kongfz.com/product/?dataType=" + dataType + "&keyword=" + keyword + "&page=1");
            headers.set("Cookie", "PHPSESSID="+cookie);

            // 创建RestTemplate实例
            RestTemplate restTemplate = new RestTemplate();
            
            // 发送请求并获取响应
            ResponseEntity<String> response = restTemplate.exchange(
                builder.toUriString(),
                HttpMethod.GET,
                new org.springframework.http.HttpEntity<>(headers),
                String.class
            );
            
            // 解析响应数据
            String responseBody = response.getBody();
            Map<String, Object> responseMap = JsonUtils.parseObject(responseBody, Map.class);
            
            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("data", responseMap);
            result.put("status", response.getStatusCode().value());
            
            return R.ok(result);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("获取商品信息失败：" + e.getMessage());
        }
    }

}
