<?php
declare(strict_types=1);

namespace App\Modules\Accounting;

/**
 * Egyptian Standard Chart of Accounts — Centralized Constants.
 *
 * 5-level hierarchy:
 *   L1 (عام/الأول)    = 1 digit   (1, 2, 3, 4)
 *   L2 (عام/الثاني)   = 2 digits  (11, 12, 21, 22, 23, 31, 32, 33, 34, 41, 42)
 *   L3 (مساعد/الثالث) = 4 digits  (1101, 1202, 1206, 2101, 2306, 3101, 4101...)
 *   L4 (فرعي/الرابع)  = 6 digits  (110101, 120601, 230601, 310101...)
 *   L5 (جزئي/الخامس) = 8 digits  (11010101, 12060101, 23060101...)
 */
final class AccountCodes
{
    // ══════════════════════════════════════════════════════════════════
    // 1 — ASSETS
    // ══════════════════════════════════════════════════════════════════

    // Cash (under 1206 = النقدية ومافي حكمها)
    const CASH_ON_HAND        = '12060101'; // الصندوق بالجنيه المصري
    const SUB_TREASURY_CASH   = '12060102'; // صندوق الخزنة الفرعية - الأنشطة الرياضية
    const CASH_AT_BANK        = '12060201'; // البنك الرئيسي - جنيه مصري

    // Receivables (under 1203/1204)
    const ACCOUNTS_RECEIVABLE = '120301';   // العملاء
    const EMPLOYEE_LOANS      = '120402';   // سلف عاملين

    // Inventory (under 1202 = المخزون)
    const INVENTORY           = '120209';   // مخزون بضائع بغرض البيع

    // Input Tax
    const INPUT_TAX           = '120408';   // ضريبة مدخلات (under مدينون وأرصدة مدينة)

    // ══════════════════════════════════════════════════════════════════
    // 2 — EQUITY & LIABILITIES
    // ══════════════════════════════════════════════════════════════════

    // 21 = حقوق الملكية (Equity)
    const CAPITAL             = '2101';     // رأس المال المدفوع
    const RETAINED_EARNINGS   = '210201';   // أرباح مرحلة

    // 22 = الإلتزامات الغير المتداولة (Non-current Liabilities)
    const LONG_TERM_LOANS     = '220101';   // قروض من بنوك عملة محلية

    // 23 = الإلتزامات المتداولة (Current Liabilities)
    const ACCOUNTS_PAYABLE    = '230601';   // الموردون
    const TAX_PAYABLE         = '230804';   // جاري مصلحة الضرائب
    const INSURANCE_PAYABLE   = '23080601'; // الهيئة القومية للتأمينات الاجتماعية
    const DEFERRED_REVENUE    = '230809';   // إيرادات مدفوعة مقدما
    const MEMBERSHIP_DEPOSITS = '230801';   // تأمينات للغير
    const ACCRUED_EXPENSES    = '230810';   // مصروفات مستحقة

    // ══════════════════════════════════════════════════════════════════
    // 3 — EXPENSES
    // ══════════════════════════════════════════════════════════════════

    // Personnel (under 3101 = الاجور والمرتبات — تكاليف النشاط)
    const SALARY_EXPENSE      = '310101';   // الاجور الاساسية
    const INSURANCE_EXPENSE   = '310103';   // حصة الشركة في التامينات

    // COGS (under 31 — مخزون بضائع بغرض البيع)
    const COGS                = '3172';     // مخزون بضائع بغرض البيع (تكلفة مبيعات)

    // Bank Charges (under 3314 = عمولة ومصروفات بنكية — مصروفات عمومية وإدارية)
    const BANK_CHARGES        = '331402';   // مصروفات بنكية

    // Depreciation (under 3316 = الاهلاكات — مصروفات عمومية وإدارية)
    const DEPRECIATION        = '3316';     // الاهلاكات

    // ══════════════════════════════════════════════════════════════════
    // 4 — REVENUE (Custom for this club)
    // ══════════════════════════════════════════════════════════════════

    // Membership Revenue (4101)
    const FORM_FEE_REVENUE           = '410101';
    const MEMBERSHIP_VALUE_REVENUE   = '410102';
    const DEPENDENT_ADDITION_REVENUE = '410103';

    // Subscription Revenue (4102)
    const ANNUAL_SUBSCRIPTION        = '410201';
    const DEVELOPMENT_FEE            = '410202';

    // Transfer & Cases Revenue (4103)
    const SEPARATION_FEE_REVENUE     = '410301';
    const DIVORCE_FEE_REVENUE        = '410302';
    const DEATH_TRANSFER_REVENUE     = '410303';
    const WAIVER_FEE_REVENUE         = '410304';
    const SPORTS_CONVERSION_REVENUE  = '410305';

    // Special Memberships (4104)
    const SEASONAL_MEMBERSHIP        = '410401';
    const CARNET_REPLACEMENT         = '410402';
    const FOREIGN_MEMBERSHIP         = '410403';

    // Activities & Sports (4105)
    const ACTIVITY_SUBSCRIPTION      = '410501';
    const ACADEMY_REVENUE            = '410502';
    const HOURLY_BOOKING_REVENUE     = '410503';

    // Single-level revenue accounts
    const FINE_REVENUE               = '4106';
    const SALES_REVENUE              = '4107';
    const RENTAL_REVENUE             = '4108';

    // Installment Revenue (4109)
    const DOWN_PAYMENT_REVENUE       = '410901';
    const INSTALLMENT_REVENUE        = '410902';

    // Other Revenue (42)
    const BANK_INTEREST_INCOME       = '4205';   // فوائد دائنة
    const MISCELLANEOUS_REVENUE      = '4202';   // إعانات / متنوعة

    // Facility & Pool Revenue (4111)
    const FACILITY_ENTRY_REVENUE     = '411101';
    const POOL_ENTRY_REVENUE         = '411102';
    const GUEST_ENTRY_REVENUE        = '411103';

    // Tournament Revenue (4112)
    const TOURNAMENT_FEE_REVENUE     = '411201';

    // Service Revenue (catch-all for deposits reclassification etc.)
    const SERVICE_REVENUE            = '4110';

    // ══════════════════════════════════════════════════════════════════
    // HELPERS
    // ══════════════════════════════════════════════════════════════════

    public static function debitAccountForMethod(string $method): string
    {
        return match ($method) {
            'cash'          => self::CASH_ON_HAND,
            'check'         => self::CASH_AT_BANK,
            'visa'          => self::CASH_AT_BANK,
            'bank_transfer' => self::CASH_AT_BANK,
            default         => self::CASH_ON_HAND,
        };
    }

    public static function debitAccountForTreasury(string $method, ?int $treasuryId = null): string
    {
        if ($method !== 'cash' || $treasuryId === null) {
            return self::debitAccountForMethod($method);
        }

        $db = \App\Core\App::getInstance()->db();
        $treasury = $db->selectOne("SELECT account_code, type FROM treasuries WHERE id = ?", [$treasuryId]);

        if ($treasury && $treasury['type'] === 'sub') {
            return $treasury['account_code'] ?: self::SUB_TREASURY_CASH;
        }

        return self::CASH_ON_HAND;
    }

    public static function creditAccountForPaymentType(string $type): string
    {
        return match ($type) {
            'form_fee'              => self::FORM_FEE_REVENUE,
            'membership_fee'        => self::MEMBERSHIP_VALUE_REVENUE,
            'addition_fee'          => self::DEPENDENT_ADDITION_REVENUE,
            'separation_fee'        => self::SEPARATION_FEE_REVENUE,
            'divorce_fee'           => self::DIVORCE_FEE_REVENUE,
            'death_fee'             => self::DEATH_TRANSFER_REVENUE,
            'waiver_fee'            => self::WAIVER_FEE_REVENUE,
            'sports_conversion'     => self::SPORTS_CONVERSION_REVENUE,
            'seasonal_fee'          => self::SEASONAL_MEMBERSHIP,
            'carnet_replacement'    => self::CARNET_REPLACEMENT,
            'annual_subscription'   => self::ANNUAL_SUBSCRIPTION,
            'development_fee'       => self::DEVELOPMENT_FEE,
            'activity_subscription' => self::ACTIVITY_SUBSCRIPTION,
            'hourly_booking'        => self::HOURLY_BOOKING_REVENUE,
            'down_payment'          => self::ACCOUNTS_RECEIVABLE,
            'installment'           => self::ACCOUNTS_RECEIVABLE,
            'fine'                  => self::FINE_REVENUE,
            'inventory_sale'        => self::SALES_REVENUE,
            default                 => self::SERVICE_REVENUE,
        };
    }
}
