package com.erp.finance.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.erp.finance.dto.*;
import com.erp.finance.entity.RefundRecord;
import com.erp.finance.service.RefundService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
import com.erp.common.core.model.ApiResponse;
import com.erp.common.core.model.PageResponse;

/**
 * 退款记录API
 */
@Slf4j
@RestController
@RequestMapping("/api/finance/refund")
@RequiredArgsConstructor
public class RefundController {

    private final RefundService refundService;

    /**
     * 创建退款记录（被order-service和aftersale-service调用）
     */
    @PostMapping("/record")
    public FinanceApiResponse<RefundRecordResponse> createRefund(@RequestBody RefundService.RefundCreateRequest request) {
        try {
            log.info("[API] 创建退款记录 orderNo={}, amount={}, type={}, source={}",
                    request.getOrderNo(), request.getRefundAmount(), request.getType(), request.getSource());
            RefundRecord record = refundService.createRefundRecord(request);
            return FinanceApiResponse.success(toResponse(record));
        } catch (Exception e) {
            log.error("[API] 创建退款记录失败 orderNo={}", request.getOrderNo(), e);
            return FinanceApiResponse.error(500, "创建退款记录失败: " + e.getMessage());
        }
    }

    /**
     * 确认退款（财务发起退款）
     */
    @PutMapping("/{id}/confirm")
    public FinanceApiResponse<RefundRecordResponse> confirmRefund(@PathVariable Long id,
                                                                   @RequestParam(required = false) String operator) {
        try {
            RefundRecord record = refundService.confirmRefund(id, operator);
            return FinanceApiResponse.success(toResponse(record));
        } catch (Exception e) {
            log.error("[API] 确认退款失败 id={}", id, e);
            return FinanceApiResponse.error(500, e.getMessage());
        }
    }

    /**
     * 完成退款（外部支付渠道回调）
     */
    @PutMapping("/{id}/complete")
    public FinanceApiResponse<RefundRecordResponse> completeRefund(@PathVariable Long id,
                                                                    @RequestParam String externalRefundNo,
                                                                    @RequestParam(required = false) String operator) {
        try {
            RefundRecord record = refundService.completeRefund(id, externalRefundNo, operator);
            return FinanceApiResponse.success(toResponse(record));
        } catch (Exception e) {
            log.error("[API] 完成退款失败 id={}", id, e);
            return FinanceApiResponse.error(500, e.getMessage());
        }
    }

    /**
     * 退款失败
     */
    @PutMapping("/{id}/fail")
    public FinanceApiResponse<?> failRefund(@PathVariable Long id,
                                            @RequestParam String reason) {
        try {
            refundService.failRefund(id, reason);
            return FinanceApiResponse.success("标记失败成功");
        } catch (Exception e) {
            log.error("[API] 退款失败标记失败 id={}", id, e);
            return FinanceApiResponse.error(500, e.getMessage());
        }
    }

    /**
     * 取消退款
     */
    @PutMapping("/{id}/cancel")
    public FinanceApiResponse<?> cancelRefund(@PathVariable Long id,
                                               @RequestParam String reason,
                                               @RequestParam(required = false) String operator) {
        try {
            refundService.cancelRefund(id, reason, operator);
            return FinanceApiResponse.success("取消成功");
        } catch (Exception e) {
            log.error("[API] 取消退款失败 id={}", id, e);
            return FinanceApiResponse.error(500, e.getMessage());
        }
    }

    /**
     * 分页查询退款记录
     */
    @GetMapping("/page")
    public FinanceApiResponse<PageResponse<RefundRecordResponse>> queryPage(
            @RequestParam(required = false) String orderNo,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String type,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") String startDate,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") String endDate,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "20") Integer pageSize) {
        RefundQueryRequest request = new RefundQueryRequest();
        request.setOrderNo(orderNo);
        request.setStatus(status);
        request.setType(type);
        request.setStartDate(startDate);
        request.setEndDate(endDate);
        request.setPage(page);
        request.setPageSize(pageSize);

        IPage<RefundRecord> result = refundService.query(request);
        return FinanceApiResponse.success(PageResponse.of(
                result.getTotal(),
                (int) result.getCurrent(),
                (int) result.getSize(),
                result.getRecords().stream().map(RefundController::toResponse).toList()
        ));
    }

    /**
     * 根据ID查询
     */
    @GetMapping("/{id}")
    public FinanceApiResponse<RefundRecordResponse> getById(@PathVariable Long id) {
        RefundRecord record = refundService.getById(id);
        if (record == null) {
            return FinanceApiResponse.notFound("退款记录不存在");
        }
        return FinanceApiResponse.success(toResponse(record));
    }

    /**
     * 根据退款单号查询
     */
    @GetMapping("/no/{refundNo}")
    public FinanceApiResponse<RefundRecordResponse> getByRefundNo(@PathVariable String refundNo) {
        RefundRecord record = refundService.getByRefundNo(refundNo);
        if (record == null) {
            return FinanceApiResponse.notFound("退款记录不存在");
        }
        return FinanceApiResponse.success(toResponse(record));
    }

    /**
     * 获取待处理退款数量
     */
    @GetMapping("/pending/count")
    public FinanceApiResponse<Map<String, Long>> getPendingCount() {
        long count = refundService.getPendingCount();
        return FinanceApiResponse.success(Map.of("pendingCount", count));
    }

    private static RefundRecordResponse toResponse(RefundRecord r) {
        return RefundRecordResponse.builder()
                .id(r.getId())
                .refundNo(r.getRefundNo())
                .orderNo(r.getOrderNo())
                .shortId(r.getShortId())
                .refundAmount(r.getRefundAmount())
                .refundReason(r.getRefundReason())
                .refundTime(r.getRefundTime())
                .incomeRecordId(r.getIncomeRecordId())
                .originalAmount(r.getOriginalAmount())
                .refundMethod(r.getRefundMethod())
                .refundAccount(r.getRefundAccount())
                .status(r.getStatus())
                .type(r.getType())
                .sourceId(r.getSourceId())
                .source(r.getSource())
                .operator(r.getOperator())
                .completeTime(r.getCompleteTime())
                .failReason(r.getFailReason())
                .externalRefundNo(r.getExternalRefundNo())
                .remark(r.getRemark())
                .createTime(r.getCreateTime())
                .build();
    }
}
