package com.haha.admin.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.haha.admin.annotation.RequirePermission;
import com.haha.common.annotation.Log;
import com.haha.common.enums.OperationType;
import com.haha.common.enums.RefundStatus;
import com.haha.common.vo.PageResult;
import com.haha.common.vo.RefundApplicationVO;
import com.haha.common.vo.RefundProductVO;
import com.haha.common.vo.Result;
import com.haha.entity.Refund;
import com.haha.entity.RefundItem;
import com.haha.service.OrderService;
import com.haha.service.RefundService;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

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

/**
 * 退款申请管理控制器
 *
 * 负责退款申请的查询、详情查看、审核等操作。
 * 基于独立的 t_refund 和 t_refund_item 表管理退款记录。
 */
@Slf4j
@RestController
@RequestMapping("/refund")
@RequiredArgsConstructor
public class RefundApplicationController {

    private final RefundService refundService;
    private final OrderService orderService;

    /**
     * 分页查询退款申请列表
     */
    @RequirePermission("order:read")
    @GetMapping("/list")
    public Result<PageResult<RefundApplicationVO>> list(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int pageSize,
            @RequestParam(required = false) String orderNo,
            @RequestParam(required = false) Integer status,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {

        if (page < 1) page = 1;
        if (pageSize > 100) pageSize = 10;

        String statusStr = null;
        if (status != null) {
            if (status == 0) {
                statusStr = RefundStatus.PENDING.getCode();
            } else if (status == 1) {
                statusStr = RefundStatus.REFUNDED.getCode();
            } else if (status == 2) {
                statusStr = RefundStatus.REJECTED.getCode();
            }
        }

        IPage<Refund> refundPage = refundService.getRefundPage(
                page, pageSize, orderNo, statusStr, startDate, endDate);

        return Result.success("查询成功", PageResult.of(refundPage, this::toRefundApplicationVO));
    }

    /**
     * 获取退款申请详情
     */
    @RequirePermission("order:read")
    @GetMapping("/{id}")
    public Result<RefundApplicationVO> getDetail(@PathVariable Long id) {
        Refund refund = refundService.getDetailById(id);
        if (refund == null) {
            return Result.error(404, "退款申请不存在");
        }
        return Result.success("查询成功", toRefundApplicationVO(refund));
    }

    /**
     * 审核退款申请
     *
     * 审核通过时，同步调用第三方退款API执行实际退款操作。
     * 审核拒绝时仅更新数据库状态。
     */
    @RequirePermission("order:update")
    @Log(module = "退款管理", operation = OperationType.UPDATE, summary = "审核退款申请")
    @PostMapping("/{id}/review")
    public Result<Void> review(@PathVariable Long id, @RequestBody ReviewRefundDTO dto) {
        Long reviewerId = getCurrentAdminId();

        if (dto.isApproved()) {
            boolean success = refundService.approveRefund(id, dto.getRemark(), reviewerId);
            if (!success) {
                return Result.error(500, "退款执行失败");
            }
            log.info("退款审核通过并执行成功 - refundId: {}", id);
            return Result.success("退款成功", null);
        } else {
            boolean success = refundService.rejectRefund(id, dto.getRemark(), reviewerId);
            if (!success) {
                return Result.error(500, "操作失败");
            }
            log.info("退款申请已拒绝 - refundId: {}", id);
            return Result.success("退款申请已拒绝", null);
        }
    }

    /**
     * 将 Refund 实体转换为 RefundApplicationVO
     */
    private RefundApplicationVO toRefundApplicationVO(Refund refund) {
        RefundApplicationVO vo = new RefundApplicationVO();
        vo.setId(refund.getId());
        vo.setApplicationNo(refund.getRefundNo());
        vo.setOrderId(refund.getOrderId());
        vo.setOrderNo(refund.getOrderNo());
        vo.setRefundAmount(refund.getRefundAmount());
        vo.setReason(refund.getReason());
        vo.setReviewRemark(refund.getRemark());
        vo.setCreateTime(refund.getCreateTime());
        vo.setReviewTime(refund.getRefundTime());
        vo.setRestoreStock(refund.getRestoreStock());

        // 状态映射：REFUNDED->1, REJECTED->2, 其他->0
        if (RefundStatus.REFUNDED.getCode().equals(refund.getStatus())) {
            vo.setStatus(1);
        } else if (RefundStatus.REJECTED.getCode().equals(refund.getStatus())) {
            vo.setStatus(2);
        } else {
            vo.setStatus(0);
        }

        // 加载用户ID
        try {
            com.haha.entity.Order order = orderService.getById(refund.getOrderId());
            if (order != null) {
                vo.setUserId(order.getUserId());
            }
        } catch (Exception e) {
            log.warn("查询订单用户ID失败 - orderId: {}", refund.getOrderId());
        }

        // 从 t_refund_item 加载实际退款商品明细
        List<RefundItem> items = refundService.getRefundItems(refund.getId());
        List<RefundProductVO> products = items.stream().map(item -> {
            RefundProductVO p = new RefundProductVO();
            p.setProductId(item.getProductId());
            p.setProductName(item.getProductName());
            p.setPic(item.getPic());
            p.setQuantity(item.getQuantity());
            p.setPrice(item.getPrice());
            return p;
        }).collect(Collectors.toList());
        vo.setRefundProducts(products);

        return vo;
    }

    private Long getCurrentAdminId() {
        try {
            return StpUtil.getLoginIdAsLong();
        } catch (Exception e) {
            log.warn("获取当前管理员ID失败，使用默认值: {}", e.getMessage());
            return 0L;
        }
    }

    @Data
    public static class ReviewRefundDTO {
        private boolean approved;
        private String remark;
    }
}
