using Books.Api.Domain.Accounts;

namespace Books.Api.EventFlow.Subscribers;

/// <summary>
/// Standard Danish chart of accounts following Danish accounting standards.
/// Account number ranges:
/// - 1xxx: Revenue (Omsætning) + Current Assets (Omsætningsaktiver)
/// - 17xx: Fixed Assets (Anlægsaktiver)
/// - 2xxx: Cost of Goods Sold (Vareforbrug)
/// - 3xxx: Equity (Egenkapital) - ONLY equity accounts per Danish standards
/// - 4xxx: Sales Expenses (Salgsomkostninger)
/// - 5xxx: Location Costs (Lokaleomkostninger) + Personnel (Personaleomkostninger)
/// - 6xxx: Vehicle/Travel Expenses (Kørselsomkostninger)
/// - 7xxx: Administrative Expenses (Administrationsomkostninger) + Liabilities
/// - 8xxx: Depreciation (Afskrivninger)
/// - 9xxx: Financial Items (Finansielle poster)
///
/// StandardAccountNumber refers to Erhvervsstyrelsens standardkontoplan for SAF-T compliance.
/// Mapping based on official SAF-T 2.0 specification (mandatory from Jan 2027).
/// </summary>
public static class StandardDanishAccounts
{
    public record StandardAccount(
        string AccountNumber,
        string Name,
        AccountType AccountType,
        string? Description,
        string? DefaultVatCode,
        string? StandardAccountNumber,
        bool IsSystemAccount = false);

    public static IEnumerable<StandardAccount> GetAll()
    {
        // =========================================
        // OMSÆTNING (Revenue) - 1xxx
        // Standard: 1010 = Salg af varer og ydelser med moms
        // =========================================
        yield return new("1000", "Salg af varer, DK", AccountType.Revenue, "Salg med 25% moms", "U25", "1010", true);
        yield return new("1010", "Salg af varer, momsfrit", AccountType.Revenue, "Momsfrit salg", null, "1010", true);
        yield return new("1050", "Salg af varer, EU", AccountType.Revenue, "EU-salg af varer", "UEU", "1050", true);
        yield return new("1100", "Salg af varer, verden", AccountType.Revenue, "Eksport uden for EU", "UEXP", "1100", true);
        yield return new("1200", "Salg af ydelser, DK", AccountType.Revenue, "Salg med 25% moms", "U25", "1010", true);
        yield return new("1250", "Salg af ydelser, EU", AccountType.Revenue, "EU-salg af ydelser", "UEU", "1210", true);
        yield return new("1300", "Salg af ydelser, verden", AccountType.Revenue, "Eksport uden for EU", "UEXP", "1310", true);
        yield return new("1400", "Øvrig omsætning", AccountType.Revenue, null, "U25", "1510");
        yield return new("1500", "Valutakursdifferencer, salg", AccountType.Revenue, null, null, "1510");

        // =========================================
        // ANLÆGSAKTIVER (Fixed Assets) - 17xx
        // Standard: 5530 = Grunde og bygninger, 5570 = Produktionsanlæg
        // =========================================
        yield return new("1710", "Bygninger", AccountType.Asset, "Ejendomme og bygninger", null, "5530");
        yield return new("1720", "Maskiner og inventar", AccountType.Asset, "Driftsmidler og maskiner", null, "5570");
        yield return new("1730", "Køretøjer", AccountType.Asset, "Biler og transportmidler", null, "5570");

        // =========================================
        // OMSÆTNINGSAKTIVER (Current Assets) - 18xx-19xx
        // Standard: 6140 = Varebeholdninger, 6190 = Tilgodehavender fra salg
        // =========================================
        yield return new("1800", "Varelager", AccountType.Asset, null, null, "6140");
        yield return new("1850", "Igangværende arbejder", AccountType.Asset, null, null, "6150");
        yield return new("1900", "Debitorer", AccountType.Asset, "Tilgodehavender fra salg", null, "6190", true);
        yield return new("1950", "Andre tilgodehavender", AccountType.Asset, null, null, "6300");

        // =========================================
        // LIKVIDE BEHOLDNINGER (Cash & Bank) - 197x-198x
        // Standard: 6470 = Kontanter, 6480 = Bankindeståender
        // =========================================
        yield return new("1970", "Bankkonto", AccountType.Asset, "Bankkonto til Open Banking", null, "6480");

        // =========================================
        // VAREFORBRUG (COGS) - 2xxx
        // Standard: 1610 = Anvendt råvarer, 2070 = Køb af ydelser
        // =========================================
        yield return new("2000", "Vareforbrug", AccountType.Cogs, "Køb af varer til videresalg", "I25", "1610");
        yield return new("2050", "EU-erhvervelser varer", AccountType.Cogs, "Varekøb fra EU-lande", "IEUV", "1610");
        yield return new("2100", "EU-erhvervelser ydelser", AccountType.Cogs, "Ydelseskøb fra EU-lande", "IEUY", "2070");
        yield return new("2150", "Varekøb verden", AccountType.Cogs, "Varekøb fra lande uden for EU", "IVV", "1610");
        yield return new("2200", "Ydelseskøb verden", AccountType.Cogs, "Ydelseskøb fra lande uden for EU", "IVY", "2070");
        yield return new("2250", "Fragt med moms", AccountType.Cogs, "Fragtomkostninger med moms", "I25", "1810");
        yield return new("2300", "Fragt uden moms", AccountType.Cogs, "Fragtomkostninger uden moms", null, "1810");
        yield return new("2400", "Valutakursdifferencer, import", AccountType.Cogs, null, null, "3690");
        yield return new("2450", "Varelagerregulering", AccountType.Cogs, null, null, "1640");
        yield return new("2800", "Fremmed arbejde", AccountType.Cogs, "Underleverandører og freelancere", "I25", "2010");

        // =========================================
        // EGENKAPITAL (Equity) - 3xxx
        // Standard: 6510 = Virksomhedskapital, 6935 = Overført resultat
        // Per Danish accounting standards, 3xxx should ONLY contain equity accounts
        // =========================================
        yield return new("3000", "Aktiekapital/Anpartskapital", AccountType.Equity, "Indskudt kapital", null, "6510", true);
        yield return new("3100", "Overkurs ved emission", AccountType.Equity, "Share premium", null, "6530");
        yield return new("3900", "Overført resultat", AccountType.Equity, "Akkumuleret resultat", null, "6935", true);
        yield return new("3910", "Årets resultat", AccountType.Equity, "Resultat for indeværende år", null, "6940", true);

        // =========================================
        // SALGSOMKOSTNINGER (Sales Expenses) - 4xxx
        // Standard: 2170 = Reklame, 2180 = Rejser og møder
        // =========================================
        yield return new("4000", "Annoncer og reklame", AccountType.Expense, "Marketing og annoncering", "I25", "2170");
        yield return new("4040", "Hotel, personale", AccountType.Expense, "Fuldt fradrag", "I25", "2180");
        yield return new("4060", "Hotel, forretningsforbindelser", AccountType.Expense, "Delvis fradrag", "I25", "2180");
        yield return new("4080", "Konferencer", AccountType.Expense, null, null, "2180");
        yield return new("4100", "Messer", AccountType.Expense, null, "I25", "2170");
        yield return new("4120", "Repræsentation, restaurant, personale", AccountType.Expense, "Fuldt fradrag", "REP", "2190");
        yield return new("4140", "Repræsentation, restaurant, forretningsforbindelser", AccountType.Expense, "Delvis fradrag", "REP", "2190");
        yield return new("4180", "Repræsentation, gaver og blomster", AccountType.Expense, "Delvis fradrag", null, "2190");
        yield return new("4280", "Rejseomkostninger", AccountType.Expense, null, null, "2180");

        // =========================================
        // LOKALEOMKOSTNINGER (Location Costs) - 50xx
        // Standard: 2150 = Lokaleomkostninger
        // =========================================
        yield return new("5000", "Husleje", AccountType.Expense, "Husleje med moms", "I25", "2150");
        yield return new("5010", "Husleje uden moms", AccountType.Expense, "Husleje uden moms", null, "2150");
        yield return new("5025", "El", AccountType.Expense, null, "I25", "2150");
        yield return new("5030", "Vand", AccountType.Expense, null, "I25", "2150");
        yield return new("5035", "Varme", AccountType.Expense, null, "I25", "2150");
        yield return new("5040", "Elafgift", AccountType.Expense, null, null, "2150");
        yield return new("5060", "Rengøring og affaldshåndtering", AccountType.Expense, null, "I25", "2150");
        yield return new("5080", "Reparation og vedligeholdelse", AccountType.Expense, null, "I25", "2150");
        yield return new("5100", "Ejendomsskat", AccountType.Expense, null, null, "2150");

        // =========================================
        // PERSONALEOMKOSTNINGER (Personnel) - 53xx
        // Standard: 2310 = Lønninger, 2330 = Pensioner
        // Moved from 3xxx to comply with Danish standards (3xxx = Equity only)
        // =========================================
        yield return new("5300", "AM-indkomst", AccountType.Personnel, "Løn til ansatte", null, "2310");
        yield return new("5310", "Arbejdsgiver ATP", AccountType.Personnel, null, null, "2350");
        yield return new("5320", "Medarbejder ATP", AccountType.Personnel, null, null, "2350");
        yield return new("5330", "Sygepenge mv.", AccountType.Personnel, null, null, "2390");
        yield return new("5340", "Personalegoder", AccountType.Personnel, "Herunder fri telefon", null, "2390");
        yield return new("5350", "B-honorar", AccountType.Personnel, null, null, "2310");
        yield return new("5360", "Barsel", AccountType.Personnel, null, null, "2390");
        yield return new("5370", "Feriepenge og SH", AccountType.Personnel, null, null, "2310");
        yield return new("5380", "Pension", AccountType.Personnel, null, null, "2330");
        yield return new("5390", "Diæter/rejsegodtgørelse", AccountType.Personnel, null, null, "2310");
        yield return new("5400", "Kørsel i egen bil", AccountType.Personnel, "Kilometergodtgørelse", null, "2140");
        yield return new("5410", "AER/AES/ATP-finansieringsbidrag", AccountType.Personnel, null, null, "2350");
        yield return new("5420", "Arbejdstøj", AccountType.Personnel, null, "I25", "2390");
        yield return new("5430", "Mad under kursus/møder", AccountType.Personnel, "Fuldt fradrag", "I25", "2180");
        yield return new("5440", "Gaver til personalet", AccountType.Personnel, "Fuldt fradrag", null, "2390");
        yield return new("5450", "Uddannelsesudgifter", AccountType.Personnel, null, "I25", "2180");
        yield return new("5460", "Regulering feriepenge", AccountType.Personnel, null, null, "2310");

        // =========================================
        // KØRSELSOMKOSTNINGER (Vehicle/Travel) - 6xxx
        // Standard: 2140 = Bilomkostninger
        // =========================================
        yield return new("6000", "Billeje (gulplade)", AccountType.Expense, null, "I25", "2140");
        yield return new("6020", "Brændstof (gulplade)", AccountType.Expense, null, "I25", "2140");
        yield return new("6040", "Vedligeholdelse af bil", AccountType.Expense, null, "I25", "2140");
        yield return new("6060", "Vægtafgift og forsikringer", AccountType.Expense, null, null, "2140");
        yield return new("6080", "Parkering", AccountType.Expense, null, "I25", "2140");
        yield return new("6100", "Broafgift", AccountType.Expense, null, "I25", "2140");
        yield return new("6120", "Taxa", AccountType.Expense, null, null, "2140");
        yield return new("6140", "Tog", AccountType.Expense, null, null, "2180");
        yield return new("6160", "Fly", AccountType.Expense, null, null, "2180");

        // =========================================
        // PASSIVER - KREDITORER (Liabilities) - 69xx
        // Standard: 7350 = Leverandører af varer og tjenesteydelser
        // =========================================
        yield return new("6900", "Kreditorer", AccountType.Liability, "Leverandørgæld", null, "7350", true);
        yield return new("6950", "Anden gæld", AccountType.Liability, null, null, "7790");

        // =========================================
        // ADMINISTRATIONSOMKOSTNINGER (Admin Expenses) - 7xxx
        // Standard: 2110 = Administrationsomkostninger
        // =========================================
        yield return new("7005", "Revision og regnskabsmæssig assistance", AccountType.Expense, null, "I25", "2110");
        yield return new("7010", "Advokat", AccountType.Expense, null, "I25", "2110");
        yield return new("7020", "Bogføringsassistance", AccountType.Expense, null, "I25", "2110");
        yield return new("7040", "Konsulentbistand", AccountType.Expense, null, "I25", "2110");
        yield return new("7060", "Kontingenter inkl. moms", AccountType.Expense, null, "I25", "2110");
        yield return new("7080", "Kontingenter ekskl. moms", AccountType.Expense, null, null, "2110");
        yield return new("7100", "Aviser", AccountType.Expense, null, null, "2110");
        yield return new("7120", "Faglitteratur", AccountType.Expense, null, "I25", "2110");
        yield return new("7160", "Erhvervsforsikringer", AccountType.Expense, null, null, "2110");
        yield return new("7200", "Kontorartikler og tryksager", AccountType.Expense, null, "I25", "2110");
        yield return new("7220", "Porto og gebyrer", AccountType.Expense, null, null, "2110");
        yield return new("7240", "Telefoni", AccountType.Expense, null, "I25", "2110");
        yield return new("7300", "Internet og webhotel", AccountType.Expense, null, "I25", "2110");
        yield return new("7320", "Køb af software", AccountType.Expense, "SaaS og licenser", "I25", "2110");
        yield return new("7360", "Offentlige bøder og gebyrer", AccountType.Expense, null, null, "2110");
        yield return new("7400", "Betalingsløsning", AccountType.Expense, "Stripe, MobilePay mv.", "I25", "2110");
        yield return new("7420", "Indløsere", AccountType.Expense, "Nets, Clearhaus mv.", null, "2110");
        yield return new("7460", "Diverse inkl. moms", AccountType.Expense, null, "I25", "2110");
        yield return new("7480", "Diverse ekskl. moms", AccountType.Expense, null, null, "2110");

        // =========================================
        // PASSIVER - SKYLDIG SKAT OG MOMS (Tax Liabilities) - 79xx
        // Standard: 7680 = Anden gæld til SKAT, 7920 = A-skat
        // =========================================
        yield return new("7900", "Skyldig moms", AccountType.Liability, "Afregning med SKAT", null, "7680", true);
        yield return new("7910", "Skyldig A-skat", AccountType.Liability, null, null, "7920", true);
        yield return new("7920", "Skyldig AM-bidrag", AccountType.Liability, null, null, "7930", true);
        yield return new("7930", "Skyldig ATP", AccountType.Liability, null, null, "7940", true);
        yield return new("7940", "Skyldig feriepenge", AccountType.Liability, null, null, "8190", true);
        yield return new("7950", "Skyldig selskabsskat", AccountType.Liability, "Selskabsskat til betaling", null, "7670", true);

        // =========================================
        // AFSKRIVNINGER (Depreciation) - 8xxx
        // Standard: 3210 = Af- og nedskrivninger af materielle og immaterielle anlægsaktiver
        // =========================================
        yield return new("8010", "Afskrivning, bygninger", AccountType.Expense, "Afskrivning på bygninger", null, "3210");
        yield return new("8020", "Afskrivning, maskiner", AccountType.Expense, "Afskrivning på maskiner og inventar", null, "3210");
        yield return new("8030", "Afskrivning, køretøjer", AccountType.Expense, "Afskrivning på køretøjer", null, "3210");
        yield return new("8040", "Småanskaffelser", AccountType.Expense, "Straksafskrivning", "I25", "3210");

        // =========================================
        // FINANSIELLE POSTER (Financial) - 9xxx
        // Standard: 3670 = Øvrige finansielle omkostninger
        // =========================================
        yield return new("9200", "Bankrenter", AccountType.Financial, null, null, "3670");
        yield return new("9210", "Leverandører mv.", AccountType.Financial, "Renter til leverandører", null, "3670");
        yield return new("9220", "Ikke-fradragsberettigede renter", AccountType.Financial, null, null, "3670");
    }
}
