package com.erp.order.settlement.controller;

import com.erp.order.settlement.dto.*;
import com.erp.order.settlement.entity.OrderSettlement;
import com.erp.order.settlement.entity.SettlementPeriod;
import com.erp.order.settlement.entity.SettlementReport;
import com.erp.order.settlement.service.OrderSettlementService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

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

/**
 * 订单结算管理控制器
 * 提供订单结算相关的RESTful API
 */
@Slf4j
@RestController
@RequestMapping("/api/settlement")
@RequiredArgsConstructor
@CrossOrigin(origins = "*")
public class OrderSettlementController {

    private final OrderSettlementService settlementService;

    // ==================== 结算记录管理 ====================

    /**
     * 获取结算记录详情
     */
    @GetMapping("/{id}")
    public ResponseEntity<ApiResponse<SettlementDTO>> getSettlementById(@PathVariable Long id) {
        OrderSettlement settlement = settlementService.getSettlementById(id);
        if (settlement == null) {
            return ResponseEntity.status(404)
                    .body(ApiResponse.notFound("结算记录不存在"));
        }
        return ResponseEntity.ok(ApiResponse.success(toDTO(settlement)));
    }

    /**
     * 根据结算单号查询
     */
    @GetMapping("/no/{settlementNo}")
    public ResponseEntity<ApiResponse<SettlementDTO>> getSettlementBySettlementNo(@PathVariable String settlementNo) {
        OrderSettlement settlement = settlementService.getSettlementBySettlementNo(settlementNo);
        if (settlement == null) {
            return ResponseEntity.status(404)
                    .body(ApiResponse.notFound("结算记录不存在"));
        }
        return ResponseEntity.ok(ApiResponse.success(toDTO(settlement)));
    }

    /**
     * 根据订单ID查询结算记录
     */
    @GetMapping("/order/{orderId}")
    public ResponseEntity<ApiResponse<SettlementDTO>> getSettlementByOrderId(@PathVariable Long orderId) {
        OrderSettlement settlement = settlementService.getSettlementByOrderId(orderId);
        if (settlement == null) {
            return ResponseEntity.status(404)
                    .body(ApiResponse.notFound("结算记录不存在"));
        }
        return ResponseEntity.ok(ApiResponse.success(toDTO(settlement)));
    }

    /**
     * 分页查询结算记录
     */
    @GetMapping("/list")
    public ResponseEntity<ApiResponse<PageResponse<SettlementDTO>>> querySettlements(
            @RequestParam(required = false) String settlementNo,
            @RequestParam(required = false) String orderShortId,
            @RequestParam(required = false) String platformOrderSn,
            @RequestParam(required = false) String platform,
            @RequestParam(required = false) Long shopId,
            @RequestParam(required = false) String settlementStatus,
            @RequestParam(required = false) Long settlementPeriodId,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate,
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize) {

        SettlementQueryRequest request = SettlementQueryRequest.builder()
                .settlementNo(settlementNo)
                .orderShortId(orderShortId)
                .platformOrderSn(platformOrderSn)
                .platform(platform)
                .shopId(shopId)
                .settlementStatus(settlementStatus)
                .settlementPeriodId(settlementPeriodId)
                .startDate(startDate)
                .endDate(endDate)
                .pageNum(pageNum)
                .pageSize(pageSize)
                .build();

        PageResponse<SettlementDTO> result = settlementService.querySettlements(request);
        return ResponseEntity.ok(ApiResponse.success(result));
    }

    /**
     * 创建结算记录
     */
    @PostMapping
    public ResponseEntity<ApiResponse<SettlementDTO>> createSettlement(@RequestBody SettlementDTO dto) {
        OrderSettlement settlement = toEntity(dto);
        OrderSettlement created = settlementService.createSettlement(settlement);
        return ResponseEntity.ok(ApiResponse.success("结算记录创建成功", toDTO(created)));
    }

    /**
     * 更新结算记录
     */
    @PutMapping("/{id}")
    public ResponseEntity<ApiResponse<SettlementDTO>> updateSettlement(
            @PathVariable Long id,
            @RequestBody SettlementDTO dto) {
        OrderSettlement existing = settlementService.getSettlementById(id);
        if (existing == null) {
            return ResponseEntity.status(404)
                    .body(ApiResponse.notFound("结算记录不存在"));
        }

        OrderSettlement settlement = toEntity(dto);
        settlement.setId(id);
        OrderSettlement updated = settlementService.updateSettlement(settlement);
        return ResponseEntity.ok(ApiResponse.success("结算记录更新成功", toDTO(updated)));
    }

    /**
     * 批量更新结算状态
     */
    @PutMapping("/batch/status")
    public ResponseEntity<ApiResponse<Map<String, Object>>> batchUpdateStatus(
            @RequestBody Map<String, Object> request) {
        @SuppressWarnings("unchecked")
        List<Long> ids = (List<Long>) request.get("ids");
        String status = (String) request.get("status");

        if (ids == null || ids.isEmpty()) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.badRequest("请选择要更新的结算记录"));
        }
        if (status == null || status.isEmpty()) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.badRequest("请指定结算状态"));
        }

        int count = settlementService.batchUpdateStatus(ids, status);
        return ResponseEntity.ok(ApiResponse.success("更新了" + count + "条结算记录",
                Map.of("updatedCount", count)));
    }

    // ==================== 结算计算 ====================

    /**
     * 计算订单结算金额
     */
    @PostMapping("/calculate/{orderId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> calculateSettlement(
            @PathVariable Long orderId,
            @RequestParam(required = false) BigDecimal commissionRate) {
        try {
            BigDecimal settlementAmount = settlementService.calculateSettlementAmount(orderId, commissionRate);
            return ResponseEntity.ok(ApiResponse.success("结算金额计算成功",
                    Map.of("orderId", orderId, "settlementAmount", settlementAmount)));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.badRequest(e.getMessage()));
        }
    }

    /**
     * 批量计算结算
     */
    @PostMapping("/calculate/batch")
    public ResponseEntity<ApiResponse<Map<String, Object>>> batchCalculateSettlement(
            @RequestBody Map<String, Object> request) {
        @SuppressWarnings("unchecked")
        List<Long> orderIds = (List<Long>) request.get("orderIds");
        BigDecimal commissionRate = request.get("commissionRate") != null
                ? new BigDecimal(request.get("commissionRate").toString())
                : null;

        if (orderIds == null || orderIds.isEmpty()) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.badRequest("请选择要计算的订单"));
        }

        List<OrderSettlement> results = settlementService.batchCalculateSettlement(orderIds, commissionRate);
        return ResponseEntity.ok(ApiResponse.success("批量计算完成",
                Map.of("total", orderIds.size(), "success", results.size(), "results", results)));
    }

    /**
     * 确认结算
     */
    @PostMapping("/{id}/confirm")
    public ResponseEntity<ApiResponse<Map<String, Object>>> confirmSettlement(@PathVariable Long id) {
        try {
            boolean success = settlementService.confirmSettlement(id);
            return ResponseEntity.ok(ApiResponse.success("结算已确认",
                    Map.of("success", success, "settlementId", id)));
        } catch (Exception e) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.badRequest(e.getMessage()));
        }
    }

    /**
     * 批量确认结算
     */
    @PostMapping("/confirm/batch")
    public ResponseEntity<ApiResponse<Map<String, Object>>> batchConfirmSettlement(
            @RequestBody Map<String, Object> request) {
        @SuppressWarnings("unchecked")
        List<Long> settlementIds = (List<Long>) request.get("settlementIds");

        if (settlementIds == null || settlementIds.isEmpty()) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.badRequest("请选择要确认的结算记录"));
        }

        int count = settlementService.batchConfirmSettlement(settlementIds);
        return ResponseEntity.ok(ApiResponse.success("批量确认完成",
                Map.of("total", settlementIds.size(), "confirmed", count)));
    }

    /**
     * 冻结结算
     */
    @PostMapping("/{id}/freeze")
    public ResponseEntity<ApiResponse<Map<String, Object>>> freezeSettlement(
            @PathVariable Long id,
            @RequestBody Map<String, String> request) {
        String reason = request.get("reason");
        try {
            boolean success = settlementService.freezeSettlement(id, reason);
            return ResponseEntity.ok(ApiResponse.success("结算已冻结",
                    Map.of("success", success, "settlementId", id, "reason", reason != null ? reason : "")));
        } catch (Exception e) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.badRequest(e.getMessage()));
        }
    }

    // ==================== 结算周期管理 ====================

    /**
     * 创建结算周期
     */
    @PostMapping("/period")
    public ResponseEntity<ApiResponse<SettlementPeriodDTO>> createSettlementPeriod(
            @RequestBody SettlementPeriodDTO dto) {
        SettlementPeriod period = toPeriodEntity(dto);
        SettlementPeriod created = settlementService.createSettlementPeriod(period);
        return ResponseEntity.ok(ApiResponse.success("结算周期创建成功", toPeriodDTO(created)));
    }

    /**
     * 查询结算周期列表
     */
    @GetMapping("/period/list")
    public ResponseEntity<ApiResponse<List<SettlementPeriodDTO>>> querySettlementPeriods(
            @RequestParam(required = false) String periodType,
            @RequestParam(required = false) String periodStatus,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {

        SettlementQueryRequest request = SettlementQueryRequest.builder()
                .startDate(startDate)
                .endDate(endDate)
                .pageNum(1)
                .pageSize(100)
                .build();

        List<SettlementPeriodDTO> periods = settlementService.querySettlementPeriods(request);
        return ResponseEntity.ok(ApiResponse.success(periods));
    }

    /**
     * 关闭结算周期
     */
    @PostMapping("/period/{id}/close")
    public ResponseEntity<ApiResponse<Map<String, Object>>> closeSettlementPeriod(@PathVariable Long id) {
        try {
            boolean success = settlementService.closeSettlementPeriod(id);
            return ResponseEntity.ok(ApiResponse.success("结算周期已关闭",
                    Map.of("success", success, "periodId", id)));
        } catch (Exception e) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.badRequest(e.getMessage()));
        }
    }

    /**
     * 结算周期内订单
     */
    @PostMapping("/period/{id}/settle")
    public ResponseEntity<ApiResponse<Map<String, Object>>> settlePeriodOrders(@PathVariable Long id) {
        int count = settlementService.settlePeriodOrders(id);
        return ResponseEntity.ok(ApiResponse.success("周期结算完成",
                Map.of("periodId", id, "settledCount", count)));
    }

    // ==================== 统计报表 ====================

    /**
     * 获取结算统计数据
     */
    @GetMapping("/statistics")
    public ResponseEntity<ApiResponse<SettlementStatisticsDTO>> getStatistics(
            @RequestParam(required = false) String platform,
            @RequestParam(required = false) Long shopId,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {

        SettlementQueryRequest request = SettlementQueryRequest.builder()
                .platform(platform)
                .shopId(shopId)
                .startDate(startDate)
                .endDate(endDate)
                .build();

        SettlementStatisticsDTO stats = settlementService.getStatistics(request);
        return ResponseEntity.ok(ApiResponse.success(stats));
    }

    /**
     * 生成结算报表
     */
    @PostMapping("/report/generate")
    public ResponseEntity<ApiResponse<SettlementReport>> generateReport(
            @RequestBody Map<String, Object> request) {
        String reportType = (String) request.get("reportType");
        Long shopId = request.get("shopId") != null ? Long.parseLong(request.get("shopId").toString()) : null;
        String platform = (String) request.get("platform");
        LocalDate startDate = request.get("startDate") != null
                ? LocalDate.parse(request.get("startDate").toString())
                : null;
        LocalDate endDate = request.get("endDate") != null
                ? LocalDate.parse(request.get("endDate").toString())
                : null;

        SettlementReport report = settlementService.generateReport(reportType, shopId, platform, startDate, endDate);
        return ResponseEntity.ok(ApiResponse.success("报表生成成功", report));
    }

    /**
     * 查询结算报表
     */
    @GetMapping("/report/list")
    public ResponseEntity<ApiResponse<List<SettlementReport>>> queryReports(
            @RequestParam(required = false) String reportType,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {

        List<SettlementReport> reports = settlementService.queryReports(reportType, startDate, endDate);
        return ResponseEntity.ok(ApiResponse.success(reports));
    }

    /**
     * 确认结算报表
     */
    @PostMapping("/report/{id}/confirm")
    public ResponseEntity<ApiResponse<Map<String, Object>>> confirmReport(@PathVariable Long id) {
        boolean success = settlementService.confirmReport(id);
        return ResponseEntity.ok(ApiResponse.success("报表已确认",
                Map.of("success", success, "reportId", id)));
    }

    // ==================== 店铺/平台维度统计 ====================

    /**
     * 获取店铺待结算金额
     */
    @GetMapping("/shop/{shopId}/pending-amount")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getShopPendingAmount(@PathVariable Long shopId) {
        BigDecimal amount = settlementService.getShopPendingSettlementAmount(shopId);
        return ResponseEntity.ok(ApiResponse.success(Map.of("shopId", shopId, "pendingAmount", amount)));
    }

    /**
     * 获取平台待结算金额
     */
    @GetMapping("/platform/{platform}/pending-amount")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getPlatformPendingAmount(@PathVariable String platform) {
        BigDecimal amount = settlementService.getPlatformPendingSettlementAmount(platform);
        return ResponseEntity.ok(ApiResponse.success(Map.of("platform", platform, "pendingAmount", amount)));
    }

    /**
     * 获取店铺结算汇总
     */
    @GetMapping("/shop/{shopId}/summary")
    public ResponseEntity<ApiResponse<SettlementStatisticsDTO.ShopStatistics>> getShopSummary(
            @PathVariable Long shopId,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {

        SettlementStatisticsDTO.ShopStatistics summary = settlementService.getShopSettlementSummary(shopId, startDate, endDate);
        if (summary == null) {
            return ResponseEntity.status(404)
                    .body(ApiResponse.notFound("未找到店铺结算汇总"));
        }
        return ResponseEntity.ok(ApiResponse.success(summary));
    }

    /**
     * 获取平台结算汇总
     */
    @GetMapping("/platform/{platform}/summary")
    public ResponseEntity<ApiResponse<SettlementStatisticsDTO.PlatformStatistics>> getPlatformSummary(
            @PathVariable String platform,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {

        SettlementStatisticsDTO.PlatformStatistics summary = settlementService.getPlatformSettlementSummary(platform, startDate, endDate);
        if (summary == null) {
            return ResponseEntity.status(404)
                    .body(ApiResponse.notFound("未找到平台结算汇总"));
        }
        return ResponseEntity.ok(ApiResponse.success(summary));
    }

    // ==================== 辅助方法 ====================

    private SettlementDTO toDTO(OrderSettlement settlement) {
        return SettlementDTO.builder()
                .id(settlement.getId())
                .settlementNo(settlement.getSettlementNo())
                .orderId(settlement.getOrderId())
                .orderShortId(settlement.getOrderShortId())
                .platformOrderSn(settlement.getPlatformOrderSn())
                .platform(settlement.getPlatform())
                .shopId(settlement.getShopId())
                .shopName(settlement.getShopName())
                .orderAmount(settlement.getOrderAmount())
                .discountAmount(settlement.getDiscountAmount())
                .freight(settlement.getFreight())
                .totalAmount(settlement.getTotalAmount())
                .platformFee(settlement.getPlatformFee())
                .platformCommissionRate(settlement.getPlatformCommissionRate())
                .settlementAmount(settlement.getSettlementAmount())
                .settlementStatus(settlement.getSettlementStatus())
                .settlementPeriodId(settlement.getSettlementPeriodId())
                .settlementDate(settlement.getSettlementDate())
                .paymentTime(settlement.getPaymentTime())
                .deliveryTime(settlement.getDeliveryTime())
                .confirmTime(settlement.getConfirmTime())
                .confirmSettlementTime(settlement.getConfirmSettlementTime())
                .remark(settlement.getRemark())
                .createdAt(settlement.getCreatedAt())
                .updatedAt(settlement.getUpdatedAt())
                .build();
    }

    private OrderSettlement toEntity(SettlementDTO dto) {
        return OrderSettlement.builder()
                .id(dto.getId())
                .settlementNo(dto.getSettlementNo())
                .orderId(dto.getOrderId())
                .orderShortId(dto.getOrderShortId())
                .platformOrderSn(dto.getPlatformOrderSn())
                .platform(dto.getPlatform())
                .shopId(dto.getShopId())
                .shopName(dto.getShopName())
                .orderAmount(dto.getOrderAmount())
                .discountAmount(dto.getDiscountAmount())
                .freight(dto.getFreight())
                .totalAmount(dto.getTotalAmount())
                .platformFee(dto.getPlatformFee())
                .platformCommissionRate(dto.getPlatformCommissionRate())
                .settlementAmount(dto.getSettlementAmount())
                .settlementStatus(dto.getSettlementStatus())
                .settlementPeriodId(dto.getSettlementPeriodId())
                .settlementDate(dto.getSettlementDate())
                .paymentTime(dto.getPaymentTime())
                .deliveryTime(dto.getDeliveryTime())
                .confirmTime(dto.getConfirmTime())
                .confirmSettlementTime(dto.getConfirmSettlementTime())
                .remark(dto.getRemark())
                .build();
    }

    private SettlementPeriodDTO toPeriodDTO(SettlementPeriod period) {
        if (period == null) return null;
        return SettlementPeriodDTO.builder()
                .id(period.getId())
                .periodNo(period.getPeriodNo())
                .periodType(period.getPeriodType())
                .startDate(period.getStartDate())
                .endDate(period.getEndDate())
                .periodStatus(period.getPeriodStatus())
                .orderCount(period.getOrderCount())
                .totalOrderAmount(period.getTotalOrderAmount())
                .totalSettlementAmount(period.getTotalSettlementAmount())
                .totalPlatformFee(period.getTotalPlatformFee())
                .settlementTime(period.getSettlementTime())
                .settleOperatorId(period.getSettleOperatorId())
                .settleOperatorName(period.getSettleOperatorName())
                .remark(period.getRemark())
                .createdAt(period.getCreatedAt())
                .updatedAt(period.getUpdatedAt())
                .build();
    }

    private SettlementPeriod toPeriodEntity(SettlementPeriodDTO dto) {
        return SettlementPeriod.builder()
                .id(dto.getId())
                .periodNo(dto.getPeriodNo())
                .periodType(dto.getPeriodType())
                .startDate(dto.getStartDate())
                .endDate(dto.getEndDate())
                .periodStatus(dto.getPeriodStatus())
                .orderCount(dto.getOrderCount())
                .totalOrderAmount(dto.getTotalOrderAmount())
                .totalSettlementAmount(dto.getTotalSettlementAmount())
                .totalPlatformFee(dto.getTotalPlatformFee())
                .settlementTime(dto.getSettlementTime())
                .settleOperatorId(dto.getSettleOperatorId())
                .settleOperatorName(dto.getSettleOperatorName())
                .remark(dto.getRemark())
                .build();
    }
}
