package com.haha.admin.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.haha.admin.annotation.RequirePermission;
import com.haha.entity.dto.OrderQueryDTO;
import com.haha.entity.dto.RefundDTO;
import com.haha.common.annotation.Log;
import com.haha.common.enums.OperationType;
import com.haha.common.vo.OrderStatisticsVO;
import com.haha.common.vo.OrderVO;
import com.haha.common.vo.PageResult;
import com.haha.common.vo.Result;
import com.haha.entity.Order;
import com.haha.service.OrderService;
import com.haha.service.HahaCallbackService;
import com.haha.service.payment.payscore.PayScoreCancelRequest;
import com.haha.service.payment.payscore.PayScoreResult;
import com.haha.service.payment.payscore.PayScoreStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

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

import com.haha.service.payment.PaymentService;
import com.haha.service.payment.RefundResult;
import com.haha.service.payment.RefundResult;

/**
 * 订单管理控制器
 */
@Slf4j
@RestController
@RequestMapping("/order")
@RequiredArgsConstructor
public class OrderController {

    private final OrderService orderService;

    @Autowired
    private HahaCallbackService hahaCallbackService;

    @Autowired(required = false)
    private PayScoreStrategy payScoreStrategy;

    @Autowired
    private PaymentService paymentService;

    /**
     * 分页查询订单列表
     */
    @RequirePermission("order:read")
    @GetMapping("/list")
    public Result<PageResult<Order>> list(OrderQueryDTO queryDTO) {
        log.info("订单列表查询参数：page={}, pageSize={}, orderNo={}, deviceId={}, phone={}, status={}, statusList={}",
                queryDTO.getPage(), queryDTO.getPageSize(),
                queryDTO.getOrderNo(), queryDTO.getDeviceId(),
                queryDTO.getPhone(), queryDTO.getStatus(), queryDTO.getStatusList());

        queryDTO.validate();

        IPage<Order> orderPage = orderService.getPage(
                queryDTO.getPage(),
                queryDTO.getPageSize(),
                queryDTO.getOrderNo(),
                queryDTO.getDeviceId(),
                queryDTO.getPayStatus(),
                queryDTO.getStatus(),
                queryDTO.getStartDate(),
                queryDTO.getEndDate(),
                queryDTO.getStatusList(),
                queryDTO.getPhone()
        );

        return Result.success("查询成功", PageResult.of(orderPage));
    }

    /**
     * 获取订单详情（包含商品列表）
     */
    @RequirePermission("order:read")
    @GetMapping("/{id}")
    public Result<OrderVO> getById(@PathVariable Long id) {
        OrderVO order = orderService.getDetailVOById(id);
        if (order == null) {
            return Result.error(404, "订单不存在");
        }
        return Result.success("查询成功", order);
    }

    /**
     * 获取订单统计数据
     */
    @RequirePermission("order:read")
    @GetMapping("/statistics")
    public Result<OrderStatisticsVO> getStatistics(
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {
        OrderStatisticsVO statistics = orderService.getStatistics(startDate, endDate);
        return Result.success("查询成功", statistics);
    }

    /**
     * 订单退款（支持选择商品退款 / 自定义金额退款 / 全额退款）
     */
    @RequirePermission("order:update")
    @Log(module = "订单管理", operation = OperationType.UPDATE, summary = "订单退款")
    @PostMapping("/{id}/refund")
    public Result<Void> refund(@PathVariable Long id, @RequestBody RefundDTO dto) {
        // 构建退款参数
        Map<String, Object> params = new HashMap<>();
        params.put("orderId", id);
        params.put("reason", dto.getReason() != null ? dto.getReason() : "管理员退款");
        params.put("immediate", true); // 管理员直接退款，立即执行

        // 如果有商品明细，传入商品列表
        if (dto.getProducts() != null && !dto.getProducts().isEmpty()) {
            List<Map<String, Object>> productMaps = dto.getProducts().stream().map(p -> {
                Map<String, Object> m = new HashMap<>();
                m.put("productId", p.getProductId());
                m.put("productName", p.getProductName());
                m.put("quantity", p.getQuantity());
                m.put("price", p.getPrice());
                return m;
            }).collect(Collectors.toList());
            params.put("products", productMaps);
        }

        // 如果有自定义退款金额
        if (dto.getRefundAmount() != null) {
            params.put("refundAmount", dto.getRefundAmount());
        }

        // 退款后是否恢复库存（前端传入）
        if (dto.getRestoreStock() != null) {
            params.put("restoreStock", dto.getRestoreStock());
        }

        // 调用支付服务执行退款
        try {
            RefundResult result = paymentService.refund(params);
            if (result.isSuccess()) {
                return Result.success("退款成功", null);
            } else {
                return Result.error(500, result.getErrorMsg() != null ? result.getErrorMsg() : "退款失败");
            }
        } catch (Exception e) {
            log.error("退款异常 - orderId: {}, error: {}", id, e.getMessage(), e);
            return Result.error(500, "退款失败：" + e.getMessage());
        }
    }

    /**
     * 手动取消支付分订单（通过 outOrderNo 直接调用微信支付分取消API）
     */
    @RequirePermission("order:update")
    @Log(module = "订单管理", operation = OperationType.UPDATE, summary = "手动取消支付分订单")
    @PostMapping("/payscore/cancel")
    public Result<Map<String, Object>> cancelPayScore(@RequestBody Map<String, String> params) {
        if (payScoreStrategy == null) {
            return Result.error(500, "支付分服务未配置，无法取消");
        }

        String outOrderNo = params.get("outOrderNo");
        if (outOrderNo == null || outOrderNo.trim().isEmpty()) {
            return Result.error(400, "outOrderNo 不能为空");
        }

        String reason = params.getOrDefault("reason", "管理员手动取消");

        try {
            PayScoreCancelRequest cancelReq = new PayScoreCancelRequest();
            cancelReq.setOutOrderNo(outOrderNo.trim());
            cancelReq.setReason(reason);

            PayScoreResult result = payScoreStrategy.cancelServiceOrder(cancelReq);

            Map<String, Object> data = new HashMap<>();
            data.put("outOrderNo", outOrderNo);
            data.put("success", result.isSuccess());
            if (result.isSuccess()) {
                data.put("state", result.getState());
                return Result.success("支付分订单取消成功", data);
            } else {
                data.put("errorCode", result.getErrorCode());
                data.put("errorMsg", result.getErrorMsg());
                return Result.error(500, "取消失败: " + result.getErrorMsg());
            }
        } catch (Exception e) {
            log.error("手动取消支付分订单失败 - outOrderNo: {}", outOrderNo, e);
            return Result.error(500, "取消异常: " + e.getMessage());
        }
    }

    /**
     * 获取订单图像（开门前后图片/视频）
     */
    @RequirePermission("order:read")
    @GetMapping("/{id}/media")
    public Result<Map<String, Object>> getOrderMedia(@PathVariable Long id,
                                                      @RequestParam(required = false) String orderId,
                                                      @RequestParam(required = false) String activityId) {
        Map<String, Object> media = hahaCallbackService.getOrderMedia(orderId, activityId);
        return Result.success("查询成功", media);
    }

    /**
     * 从哈哈平台同步查询订单（对账补偿）
     */
    @RequirePermission("order:read")
    @GetMapping("/query-from-haha")
    public Result<Map<String, Object>> queryFromHaha(@RequestParam(required = false) String orderId,
                                                      @RequestParam(required = false) String activityId) {
        Map<String, Object> result = hahaCallbackService.queryOrderFromHaha(orderId, activityId);
        return Result.success("查询成功", result);
    }

    /**
     * 获取静态柜分层识别结果
     */
    @RequirePermission("order:read")
    @GetMapping("/layer-recognize")
    public Result<Map<String, Object>> getLayerRecognize(@RequestParam(required = false) String orderId,
                                                          @RequestParam(required = false) String activityId) {
        Map<String, Object> result = hahaCallbackService.getLayerRecognize(orderId, activityId);
        return Result.success("查询成功", result);
    }

    /**
     * 修复缺失商品记录的订单：解析 items (sku_list) 补写 t_order_goods
     * 传 activityId 修复单个，不传则批量修复所有
     */
    @RequirePermission("order:update")
    @PostMapping("/repair-goods")
    public Result<Map<String, Object>> repairOrdersMissingGoods(
            @RequestParam(required = false) String activityId,
            @RequestParam(required = false, defaultValue = "false") boolean syncPayStatus) {
        com.haha.service.impl.OrderServiceImpl impl = (com.haha.service.impl.OrderServiceImpl) orderService;
        if (syncPayStatus) {
            Map<String, Object> data = impl.repairPayStatusSync();
            return Result.success("同步完成", data);
        }
        int fixed = impl.repairOrdersMissingGoods(activityId);
        Map<String, Object> data = new HashMap<>();
        data.put("fixed", fixed);
        return Result.success("修复完成", data);
    }

    /**
     * 修复指定订单的支付分扣费
     */
    @RequirePermission("order:update")
    @PostMapping("/repair-payscore")
    public Result<Map<String, Object>> repairPayScorePayment(@RequestBody Map<String, Object> params) {
        Object orderIdObj = params.get("orderId");
        if (orderIdObj == null || orderIdObj.toString().trim().isEmpty()) {
            return Result.error("orderId 不能为空");
        }
        String input = orderIdObj.toString().trim();
        Object outOrderNoObj = params.get("outOrderNo");
        String outOrderNo = outOrderNoObj != null ? outOrderNoObj.toString().trim() : null;
        com.haha.service.impl.OrderServiceImpl impl = (com.haha.service.impl.OrderServiceImpl) orderService;
        Map<String, Object> data = impl.repairPayScorePayment(input, outOrderNo);
        return (boolean) data.get("success") ? Result.success((String) data.get("message"), data) : Result.error((String) data.get("message"));
    }
}
