namespace Books.Api.Domain;

/// <summary>
/// Danish VAT (moms) codes for SKAT compliance.
/// These codes determine how transactions are reported in the VAT return.
/// </summary>
public static class VatCodes
{
    // Output VAT (Udgående moms) - Sales
    public const string U25 = "U25";       // Salg med 25% moms (standard)
    public const string UEU = "UEU";       // EU-salg af varer/ydelser (momsfrit)
    public const string UEXP = "UEXP";     // Eksport uden for EU (momsfrit)

    // Input VAT (Indgående moms) - Purchases
    public const string I25 = "I25";       // Køb med 25% moms (fuldt fradrag)
    public const string IEUV = "IEUV";     // EU-erhvervelse varer (reverse charge)
    public const string IEUY = "IEUY";     // EU-erhvervelse ydelser (reverse charge)
    public const string IVV = "IVV";       // Import varer fra verden
    public const string IVY = "IVY";       // Import ydelser fra verden

    // Special codes
    public const string REP = "REP";       // Repræsentation (25% fradrag)
    public const string INGEN = "INGEN";   // Ingen moms / momsfrit

    /// <summary>
    /// Gets the VAT rate for a given code.
    /// </summary>
    public static decimal GetRate(string? vatCode) => vatCode switch
    {
        U25 => 0.25m,
        I25 => 0.25m,
        IEUV => 0.25m,  // Reverse charge - calculated but offset
        IEUY => 0.25m,  // Reverse charge - calculated but offset
        REP => 0.25m,   // 25% rate, but only 25% deductible
        _ => 0m
    };

    /// <summary>
    /// Gets the deductible percentage for a given code.
    /// </summary>
    public static decimal GetDeductiblePercent(string? vatCode) => vatCode switch
    {
        I25 => 1.0m,    // 100% deductible
        IEUV => 1.0m,   // 100% deductible (reverse charge)
        IEUY => 1.0m,   // 100% deductible (reverse charge)
        REP => 0.25m,   // Only 25% deductible
        _ => 0m
    };

    /// <summary>
    /// Validates if a VAT code is valid.
    /// </summary>
    public static bool IsValid(string? vatCode)
    {
        if (string.IsNullOrWhiteSpace(vatCode)) return true; // null/empty is allowed
        return vatCode is U25 or UEU or UEXP or I25 or IEUV or IEUY or IVV or IVY or REP or INGEN;
    }

    /// <summary>
    /// Determines if this is input VAT (købsmoms/fradrag) vs output VAT (salgsmoms/skyldig).
    /// Input VAT is on purchases (assets), output VAT is on sales (liabilities).
    /// </summary>
    public static bool IsInputVat(string? vatCode) => vatCode switch
    {
        I25 or IEUV or IEUY or IVV or IVY or REP => true,  // Purchase/input VAT codes
        U25 or UEU or UEXP => false,                       // Sales/output VAT codes
        _ => false
    };

    /// <summary>
    /// All valid VAT codes for UI dropdowns.
    /// </summary>
    public static IReadOnlyList<VatCodeInfo> All { get; } =
    [
        new(INGEN, "Ingen moms", "No VAT", 0m),
        new(U25, "Salg 25%", "Sales 25%", 0.25m),
        new(UEU, "EU-salg", "EU Sales", 0m),
        new(UEXP, "Eksport", "Export", 0m),
        new(I25, "Køb 25%", "Purchase 25%", 0.25m),
        new(IEUV, "EU-køb varer", "EU Purchase Goods", 0.25m),
        new(IEUY, "EU-køb ydelser", "EU Purchase Services", 0.25m),
        new(IVV, "Import varer", "Import Goods", 0m),
        new(IVY, "Import ydelser", "Import Services", 0m),
        new(REP, "Repræsentation", "Entertainment", 0.25m),
    ];
}

public record VatCodeInfo(string Code, string NameDanish, string NameEnglish, decimal Rate);
