package com.erp.invoice.controller;

import com.erp.invoice.dto.InvoiceRequest;
import com.erp.invoice.dto.InvoiceResponse;
import com.erp.invoice.service.InvoiceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

/**
 * 发票管理控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/invoices")
@RequiredArgsConstructor
@Tag(name = "发票管理", description = "发票申请、开具、作废等全生命周期管理")
public class InvoiceController {
    
    private final InvoiceService invoiceService;
    
    // ==================== CRUD操作 ====================
    
    @GetMapping
    @Operation(summary = "获取发票列表", description = "分页查询发票列表，支持多种过滤条件")
    public Map<String, Object> listInvoices(
            @Parameter(description = "租户ID") @RequestParam(required = false) Long tenantId,
            @Parameter(description = "发票状态：0-待审核, 1-已开具, 2-已作废, 3-已红冲") @RequestParam(required = false) Integer status,
            @Parameter(description = "发票类型：1-专用发票, 2-普通发票, 3-电子发票, 4-卷式发票") @RequestParam(required = false) Integer invoiceType,
            @Parameter(description = "关键词搜索（发票号、购方名称、订单号）") @RequestParam(required = false) String keyword,
            @Parameter(description = "开始日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer page,
            @Parameter(description = "每页数量") @RequestParam(defaultValue = "20") Integer size) {
        
        return invoiceService.listInvoices(tenantId, status, invoiceType, keyword, startDate, endDate, page, size);
    }
    
    @GetMapping("/{id}")
    @Operation(summary = "获取发票详情", description = "根据ID获取发票详细信息")
    public InvoiceResponse getInvoiceById(
            @Parameter(description = "发票ID") @PathVariable Long id) {
        return invoiceService.getInvoiceById(id);
    }
    
    @GetMapping("/no/{invoiceNo}")
    @Operation(summary = "根据发票号获取发票", description = "根据发票号获取发票信息")
    public InvoiceResponse getInvoiceByInvoiceNo(
            @Parameter(description = "发票号") @PathVariable String invoiceNo) {
        return invoiceService.getInvoiceByInvoiceNo(invoiceNo);
    }
    
    // ==================== 发票申请 ====================
    
    @PostMapping
    @Operation(summary = "创建发票申请", description = "创建新的发票申请单")
    public InvoiceResponse createInvoice(
            @Valid @RequestBody InvoiceRequest request,
            @Parameter(description = "申请人ID") @RequestHeader(value = "X-User-Id", required = false) Long applicantId,
            @Parameter(description = "申请人名称") @RequestHeader(value = "X-User-Name", required = false) String applicantName) {
        
        log.info("创建发票申请: applicantId={}, applicantName={}", applicantId, applicantName);
        return invoiceService.createInvoice(request, applicantId, applicantName);
    }
    
    @PutMapping("/{id}")
    @Operation(summary = "更新发票申请", description = "更新发票申请信息（仅限待审核状态）")
    public InvoiceResponse updateInvoice(
            @Parameter(description = "发票ID") @PathVariable Long id,
            @Valid @RequestBody InvoiceRequest request) {
        
        return invoiceService.updateInvoice(id, request);
    }
    
    @DeleteMapping("/{id}")
    @Operation(summary = "删除发票申请", description = "删除发票申请（仅限待审核状态）")
    public void deleteInvoice(
            @Parameter(description = "发票ID") @PathVariable Long id) {
        invoiceService.deleteInvoice(id);
    }
    
    // ==================== 发票审核 ====================
    
    @PostMapping("/{id}/audit")
    @Operation(summary = "审核发票申请", description = "审核发票申请，通过或拒绝")
    public InvoiceResponse auditInvoice(
            @Parameter(description = "发票ID") @PathVariable Long id,
            @Parameter(description = "审核状态：1-通过, 0-拒绝") @RequestParam Integer auditStatus,
            @Parameter(description = "审核人ID") @RequestHeader(value = "X-User-Id", required = false) Long auditorId,
            @Parameter(description = "审核人名称") @RequestHeader(value = "X-User-Name", required = false) String auditorName,
            @Parameter(description = "审核备注") @RequestParam(required = false) String auditRemark) {
        
        return invoiceService.auditInvoice(id, auditStatus, auditorId, auditorName, auditRemark);
    }
    
    // ==================== 发票开具 ====================
    
    @PostMapping("/{id}/issue")
    @Operation(summary = "开具发票", description = "开具正式发票，生成发票号")
    public InvoiceResponse issueInvoice(
            @Parameter(description = "发票ID") @PathVariable Long id,
            @Parameter(description = "发票号码") @RequestParam(required = false) String invoiceNo,
            @Parameter(description = "发票代码") @RequestParam(required = false) String invoiceCode,
            @Parameter(description = "开票日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate invoiceDate,
            @Parameter(description = "开票人ID") @RequestHeader(value = "X-User-Id", required = false) Long issuerId,
            @Parameter(description = "开票人名称") @RequestHeader(value = "X-User-Name", required = false) String issuerName,
            @Parameter(description = "开票人") @RequestParam(required = false) String drawer,
            @Parameter(description = "复核人") @RequestParam(required = false) String reviewer,
            @Parameter(description = "收款人") @RequestParam(required = false) String payee) {
        
        if (invoiceDate == null) {
            invoiceDate = LocalDate.now();
        }
        
        return invoiceService.issueInvoice(id, invoiceNo, invoiceCode, invoiceDate, issuerId, issuerName, drawer, reviewer, payee);
    }
    
    // ==================== 发票作废/红冲 ====================
    
    @PostMapping("/{id}/void")
    @Operation(summary = "作废发票", description = "作废已开具的发票")
    public InvoiceResponse voidInvoice(
            @Parameter(description = "发票ID") @PathVariable Long id,
            @Parameter(description = "作废原因") @RequestParam String reason,
            @Parameter(description = "操作人ID") @RequestHeader(value = "X-User-Id", required = false) Long operatorId,
            @Parameter(description = "操作人名称") @RequestHeader(value = "X-User-Name", required = false) String operatorName) {
        
        return invoiceService.voidInvoice(id, reason, operatorId, operatorName);
    }
    
    @PostMapping("/{id}/reverse")
    @Operation(summary = "红冲发票", description = "红冲已开具的发票（开具负数发票）")
    public InvoiceResponse reverseInvoice(
            @Parameter(description = "发票ID") @PathVariable Long id,
            @Parameter(description = "红冲原因") @RequestParam String reason,
            @Parameter(description = "操作人ID") @RequestHeader(value = "X-User-Id", required = false) Long operatorId,
            @Parameter(description = "操作人名称") @RequestHeader(value = "X-User-Name", required = false) String operatorName) {
        
        return invoiceService.reverseInvoice(id, reason, operatorId, operatorName);
    }
    
    // ==================== 发票查询 ====================
    
    @GetMapping("/order/{orderId}")
    @Operation(summary = "根据订单ID获取发票列表", description = "获取指定订单关联的所有发票")
    public List<InvoiceResponse> getInvoicesByOrderId(
            @Parameter(description = "订单ID") @PathVariable Long orderId) {
        return invoiceService.getInvoicesByOrderId(orderId);
    }
    
    @GetMapping("/customer/{customerId}")
    @Operation(summary = "根据客户ID获取发票列表", description = "获取指定客户的所有发票")
    public List<InvoiceResponse> getInvoicesByCustomerId(
            @Parameter(description = "客户ID") @PathVariable Long customerId) {
        return invoiceService.getInvoicesByCustomerId(customerId);
    }
    
    @GetMapping("/tenant/{tenantId}/amount")
    @Operation(summary = "获取租户已开具发票总金额", description = "统计租户已开具发票的总额")
    public BigDecimal getIssuedAmountByTenant(
            @Parameter(description = "租户ID") @PathVariable Long tenantId) {
        return invoiceService.getIssuedAmountByTenant(tenantId);
    }
    
    @GetMapping("/tenant/{tenantId}/count")
    @Operation(summary = "获取日期范围内发票数量", description = "统计指定日期范围内的发票数量")
    public Integer countInvoicesByDateRange(
            @Parameter(description = "租户ID") @PathVariable Long tenantId,
            @Parameter(description = "开始日期") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @Parameter(description = "结束日期") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
        return invoiceService.countInvoicesByDateRange(tenantId, startDate, endDate);
    }
    
    // ==================== 发票文件 ====================
    
    @PutMapping("/{id}/pdf")
    @Operation(summary = "更新发票PDF路径", description = "上传发票PDF后更新路径")
    public InvoiceResponse updatePdfPath(
            @Parameter(description = "发票ID") @PathVariable Long id,
            @Parameter(description = "PDF文件路径") @RequestParam String pdfPath) {
        return invoiceService.updatePdfPath(id, pdfPath);
    }
    
    @PutMapping("/{id}/image")
    @Operation(summary = "更新发票图片路径", description = "上传发票图片后更新路径")
    public InvoiceResponse updateImagePath(
            @Parameter(description = "发票ID") @PathVariable Long id,
            @Parameter(description = "图片文件路径") @RequestParam String imagePath) {
        return invoiceService.updateImagePath(id, imagePath);
    }
    
    // ==================== 发票明细 ====================
    
    @GetMapping("/{id}/items")
    @Operation(summary = "获取发票明细", description = "获取发票的所有明细行项目")
    public List<InvoiceResponse.InvoiceItemResponse> getInvoiceItems(
            @Parameter(description = "发票ID") @PathVariable Long id) {
        return invoiceService.getInvoiceItems(id);
    }
}
