using System.ComponentModel.DataAnnotations;
using PowderCoating.Core.Enums;
using PowderCoating.Application.DTOs.GiftCertificate;

namespace PowderCoating.Application.DTOs.Invoice;

public class InvoiceListDto
{
    public int Id { get; set; }
    public string InvoiceNumber { get; set; } = string.Empty;
    public int? JobId { get; set; }
    public string? JobNumber { get; set; }
    public int CustomerId { get; set; }
    public string CustomerName { get; set; } = string.Empty;
    public InvoiceStatus Status { get; set; }
    public DateTime InvoiceDate { get; set; }
    public DateTime? DueDate { get; set; }
    public decimal Total { get; set; }
    public decimal AmountPaid { get; set; }
    public decimal BalanceDue { get; set; }
    public bool IsOverdue => Status != InvoiceStatus.Paid && Status != InvoiceStatus.Voided
        && Status != InvoiceStatus.WrittenOff && DueDate.HasValue && DueDate.Value < DateTime.UtcNow;
}

public class InvoiceDto
{
    public int Id { get; set; }
    public string InvoiceNumber { get; set; } = string.Empty;
    public int? JobId { get; set; }
    public string? JobNumber { get; set; }
    public int CustomerId { get; set; }
    public string CustomerName { get; set; } = string.Empty;
    public string? CustomerEmail { get; set; }
    public string? CustomerPhone { get; set; }
    public string? CustomerMobilePhone { get; set; }
    public string? CustomerAddress { get; set; }
    public string? CustomerCity { get; set; }
    public string? CustomerState { get; set; }
    public string? CustomerZipCode { get; set; }
    public bool CustomerNotifyByEmail { get; set; }
    public bool CustomerNotifyBySms { get; set; }
    public string? PreparedById { get; set; }
    public string? PreparedByName { get; set; }
    public InvoiceStatus Status { get; set; }
    public DateTime InvoiceDate { get; set; }
    public DateTime? DueDate { get; set; }
    public DateTime? SentDate { get; set; }
    public DateTime? PaidDate { get; set; }
    public decimal SubTotal { get; set; }
    public decimal TaxPercent { get; set; }
    public decimal TaxAmount { get; set; }
    public decimal DiscountAmount { get; set; }
    public decimal Total { get; set; }
    public decimal AmountPaid { get; set; }
    public decimal BalanceDue { get; set; }
    public string? Notes { get; set; }
    public string? InternalNotes { get; set; }
    public string? Terms { get; set; }
    public string? CustomerPO { get; set; }
    public string? ProjectName { get; set; }
    public string? ExternalReference { get; set; }
    public int? SalesTaxAccountId { get; set; }
    public string? SalesTaxAccountName { get; set; }
    public decimal CreditApplied { get; set; }
    public decimal GiftCertificateRedeemed { get; set; }
    // Online payments (Stripe Connect)
    public OnlinePaymentStatus OnlinePaymentStatus { get; set; }
    public string? PaymentLinkToken { get; set; }
    public DateTime? PaymentLinkExpiresAt { get; set; }
    public decimal OnlineAmountPaid { get; set; }
    public List<InvoiceItemDto> InvoiceItems { get; set; } = new();
    public List<PaymentDtos.PaymentDto> Payments { get; set; } = new();
    public List<RefundDto> Refunds { get; set; } = new();
    public List<CreditMemoApplicationDto> CreditApplications { get; set; } = new();
    public List<GiftCertificateRedemptionDto> GiftCertificateRedemptions { get; set; } = new();
}

public class CreateInvoiceDto
{
    public int? JobId { get; set; }
    [Range(1, int.MaxValue, ErrorMessage = "Please select a customer.")]
    public int CustomerId { get; set; }
    public string? PreparedById { get; set; }
    public DateTime InvoiceDate { get; set; } = DateTime.Today;
    public DateTime? DueDate { get; set; }
    public decimal TaxPercent { get; set; }
    public decimal DiscountAmount { get; set; }
    public string? Notes { get; set; }
    public string? InternalNotes { get; set; }
    public string? Terms { get; set; }
    public string? CustomerPO { get; set; }
    public string? ProjectName { get; set; }
    /// <summary>Early-payment discount percentage parsed from the customer's payment terms (e.g., 2.0 for "2/10 Net 30"). Informational — does not auto-apply.</summary>
    public decimal EarlyPaymentDiscountPercent { get; set; }
    /// <summary>Number of days within which the early-payment discount applies (e.g., 10 for "2/10 Net 30").</summary>
    public int EarlyPaymentDiscountDays { get; set; }
    public List<CreateInvoiceItemDto> InvoiceItems { get; set; } = new();
}

public class UpdateInvoiceDto
{
    public DateTime InvoiceDate { get; set; }
    public DateTime? DueDate { get; set; }
    public decimal TaxPercent { get; set; }
    public decimal DiscountAmount { get; set; }
    public string? Notes { get; set; }
    public string? InternalNotes { get; set; }
    public string? Terms { get; set; }
    public string? CustomerPO { get; set; }
    public string? ProjectName { get; set; }
    public List<CreateInvoiceItemDto> InvoiceItems { get; set; } = new();
}

public class InvoiceItemDto
{
    public int Id { get; set; }
    public int InvoiceId { get; set; }
    public int? SourceJobItemId { get; set; }
    public int? CatalogItemId { get; set; }
    public string Description { get; set; } = string.Empty;
    public decimal Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal TotalPrice { get; set; }
    public string? ColorName { get; set; }
    public string? Notes { get; set; }
    public int DisplayOrder { get; set; }
    public int? RevenueAccountId { get; set; }
    public string? RevenueAccountName { get; set; }
    public bool IsGiftCertificate { get; set; }
    public int? GeneratedGiftCertificateId { get; set; }
    public string? GeneratedGiftCertificateCode { get; set; }
}

public class CreateInvoiceItemDto
{
    public int? SourceJobItemId { get; set; }
    public int? CatalogItemId { get; set; }
    public string Description { get; set; } = string.Empty;
    public decimal Quantity { get; set; } = 1;
    public decimal UnitPrice { get; set; }
    public decimal TotalPrice { get; set; }
    public string? ColorName { get; set; }
    public string? Notes { get; set; }
    public int DisplayOrder { get; set; }
    public int? RevenueAccountId { get; set; }
    public bool IsGiftCertificate { get; set; } = false;
    public string? GcRecipientName { get; set; }
    public string? GcRecipientEmail { get; set; }
    public DateTime? GcExpiryDate { get; set; }
}
