<?php

declare(strict_types=1);

namespace App\Shared\Security;

final class PermissionCatalog
{
    /**
     * Canonical permissions added by the refactor/stabilization layers.
     * Legacy permissions remain supported through aliases in Authorization.
     *
     * @return array<int, array{0:string,1:string,2:string}>
     */
    public static function definitions(): array
    {
        return [
            ['roles.view', 'عرض الأدوار والصلاحيات', 'security'],
            ['roles.edit', 'تعديل الأدوار والصلاحيات', 'security'],
            ['users.view', 'عرض المستخدمين', 'security'],
            ['users.edit', 'إدارة المستخدمين', 'security'],
            ['users.create', 'إضافة مستخدم', 'security'],
            ['admin.logs.view', 'عرض سجلات النظام', 'admin'],
            ['admin.backup.create', 'إنشاء نسخة احتياطية', 'admin'],
            ['admin.backup.restore', 'استرجاع نسخة احتياطية', 'admin'],
            ['admin.data.wipe', 'تفريغ/مسح البيانات', 'admin'],
            ['admin.company.edit', 'تعديل تعريف الشركة', 'admin'],
            ['admin.comms.edit', 'تعديل إعدادات البريد والواتساب', 'admin'],
            ['admin.print_settings.edit', 'تعديل إعدادات الطباعة', 'admin'],
            ['admin.label_definitions.edit', 'إدارة تعريفات الاختصارات والتعريب', 'admin'],
            ['admin.import_data', 'استيراد البيانات من Excel', 'admin'],
            ['inventory.barcode.print', 'طباعة باركود الأصناف', 'inventory'],
            ['alerts.view', 'عرض لوحة التنبيهات', 'alerts'],

            ['customers.view', 'عرض العملاء', 'sales'],
            ['customers.edit', 'إضافة/تعديل العملاء', 'sales'],
            ['customers.create', 'إضافة عميل', 'sales'],
            ['sales.invoices.view', 'عرض فواتير المبيعات', 'sales'],
            ['sales.invoices.create', 'إنشاء فاتورة مبيعات', 'sales'],
            ['sales.invoices.edit', 'تعديل فاتورة مبيعات', 'sales'],
            ['sales.invoices.post', 'ترحيل فاتورة مبيعات', 'sales'],
            ['sales.invoices.print', 'طباعة فاتورة مبيعات', 'sales'],
            ['sales.receipts.view', 'عرض سندات القبض', 'sales'],
            ['sales.receipts.create', 'إنشاء سند قبض', 'sales'],
            ['sales.receipts.print', 'طباعة سند قبض', 'sales'],
            ['sales.statement.view', 'عرض كشف حساب العميل', 'sales'],
            ['sales_returns.view', 'عرض مرتجعات البيع', 'sales'],
            ['sales_returns.create', 'إنشاء مرتجع بيع', 'sales'],
            ['sales_returns.post', 'ترحيل مرتجع بيع', 'sales'],
            ['sales_returns.cancel', 'إلغاء مرتجع بيع', 'sales'],
            ['sales.pos', 'استخدام نقطة البيع', 'sales'],
            ['quotations.view', 'عرض عروض الأسعار', 'sales'],
            ['quotations.create', 'إنشاء عرض سعر', 'sales'],
            ['quotations.edit', 'تعديل عروض الأسعار', 'sales'],
            ['quotations.print', 'طباعة عروض الأسعار', 'sales'],
            ['quotations.send', 'إرسال عروض الأسعار', 'sales'],
            ['quotations.convert', 'تحويل عرض السعر', 'sales'],

            ['suppliers.view', 'عرض الموردين', 'purchases'],
            ['suppliers.edit', 'إضافة/تعديل الموردين', 'purchases'],
            ['suppliers.create', 'إضافة مورد', 'purchases'],
            ['purchases.view', 'عرض فواتير الشراء', 'purchases'],
            ['purchases.create', 'إنشاء فاتورة شراء', 'purchases'],
            ['purchases.edit', 'تعديل فاتورة شراء', 'purchases'],
            ['purchases.post', 'ترحيل فاتورة شراء', 'purchases'],
            ['purchases.print', 'طباعة فاتورة شراء', 'purchases'],
            ['purchase_returns.view', 'عرض مرتجعات الشراء', 'purchases'],
            ['purchase_returns.create', 'إنشاء مرتجع شراء', 'purchases'],
            ['purchase_returns.post', 'ترحيل مرتجع شراء', 'purchases'],
            ['purchase_returns.print', 'طباعة مرتجع شراء', 'purchases'],
            ['suppliers.statement.view', 'عرض كشف حساب المورد', 'purchases'],
            ['suppliers.statement.print', 'طباعة كشف حساب المورد', 'purchases'],
            ['supplier_payments.view', 'عرض مدفوعات الموردين', 'purchases'],
            ['supplier_payments.create', 'إنشاء مدفوعات الموردين', 'purchases'],
            ['supplier_payments.edit', 'تعديل مدفوعات الموردين', 'purchases'],
            ['supplier_payments.post', 'ترحيل مدفوعات الموردين', 'purchases'],
            ['supplier_payments.print', 'طباعة مدفوعات الموردين', 'purchases'],
            ['suppliers.aging.view', 'عرض تقرير أعمار ديون الموردين', 'purchases'],
            ['purchases.reports.view', 'عرض تقارير المشتريات', 'purchases'],

            ['parties.view', 'عرض الأطراف', 'parties'],
            ['parties.edit', 'إضافة/تعديل الأطراف', 'parties'],
            ['parties.create', 'إضافة طرف', 'parties'],

            ['cashboxes.view', 'عرض الخزن', 'cashbox'],
            ['cashboxes.create', 'إضافة/تعديل خزنة', 'cashbox'],
            ['cashboxes.txn.create', 'إضافة حركة خزنة', 'cashbox'],
            ['cashboxes.report.view', 'عرض كشف حركة خزنة', 'cashbox'],
            ['cash.payments.view', 'عرض سندات الصرف', 'cashbox'],
            ['cash.payments.create', 'إنشاء سند صرف', 'cashbox'],
            ['cash.payments.print', 'طباعة سند صرف', 'cashbox'],
            ['cash.payments.cancel_expense', 'إلغاء سند صرف مصروف', 'cashbox'],

            ['banks.accounts.view', 'عرض الحسابات البنكية', 'banks'],
            ['banks.accounts.edit', 'إضافة/تعديل حساب بنكي', 'banks'],
            ['banks.accounts.create', 'إضافة حساب بنكي', 'banks'],
            ['banks.txns.view', 'عرض حركات البنوك', 'banks'],
            ['banks.txns.create', 'إضافة حركة بنك', 'banks'],

            ['checks.view', 'عرض الشيكات', 'checks'],
            ['checks.create', 'استلام شيك', 'checks'],
            ['checks.endorse', 'تظهير شيك', 'checks'],
            ['checks.return', 'إرجاع شيك', 'checks'],
            ['checks.settle', 'تسوية شيك', 'checks'],
            ['checks.replace', 'استبدال شيك', 'checks'],

            ['expenses.categories.view', 'عرض مجموعات المصروفات', 'expenses'],
            ['expenses.categories.create', 'إضافة/تعديل مجموعات المصروفات', 'expenses'],
            ['expenses.items.view', 'عرض بنود المصروفات', 'expenses'],
            ['expenses.items.create', 'إضافة/تعديل بنود المصروفات', 'expenses'],
            ['expenses.report.view', 'عرض تقارير المصروفات', 'expenses'],

            ['items.view', 'عرض الأصناف', 'inventory'],
            ['items.create', 'إضافة/تعديل الأصناف', 'inventory'],
            ['categories.view', 'عرض التصنيفات', 'inventory'],
            ['categories.create', 'إضافة/تعديل التصنيفات', 'inventory'],
            ['units.view', 'عرض الوحدات', 'inventory'],
            ['units.create', 'إضافة/تعديل الوحدات', 'inventory'],
            ['warehouses.view', 'عرض المخازن', 'inventory'],
            ['warehouses.create', 'إضافة/تعديل المخازن', 'inventory'],
            ['opening_stock.manage', 'إدارة الأرصدة الافتتاحية', 'inventory'],
            ['stock.vouchers.view', 'عرض أذون المخزون', 'inventory'],

            ['employees.view', 'عرض الموظفين', 'hr'],
            ['employees.create', 'إضافة/تعديل الموظفين', 'hr'],
            ['employees.advances.create', 'تسجيل سلف الموظفين', 'hr'],
            ['employees.custodies.create', 'تسجيل عهد الموظفين', 'hr'],
            ['employees.adjustments.create', 'تسجيل تسويات الموظفين', 'hr'],
            ['payroll.view', 'عرض مسيرات الرواتب', 'hr'],
            ['payroll.create', 'إنشاء مسير رواتب', 'hr'],
            ['payroll.approve', 'اعتماد مسير رواتب', 'hr'],
            ['payroll.pay', 'صرف الرواتب', 'hr'],
        ];
    }

    /**
     * Transitional aliases kept until DB roles are fully normalized.
     *
     * @return array<string, array<int, string>>
     */
    public static function aliases(): array
    {
        return [
            'users.create' => ['users.edit'],
            'users.edit' => ['users.create'],
            'customers.create' => ['customers.edit', 'parties.edit'],
            'customers.edit' => ['customers.create', 'parties.edit'],
            'suppliers.create' => ['suppliers.edit', 'parties.edit'],
            'suppliers.edit' => ['suppliers.create', 'parties.edit'],
            'parties.create' => ['parties.edit', 'customers.edit', 'suppliers.edit'],
            'parties.edit' => ['parties.create', 'customers.edit', 'suppliers.edit'],
            'banks.accounts.create' => ['banks.accounts.edit'],
            'banks.accounts.edit' => ['banks.accounts.create'],
            'quotations.create' => ['quotations.edit'],
            'quotations.edit' => ['quotations.create'],

            // Transitional inventory/POS mapping until dedicated role assignments are normalized.
            'items.view' => ['items.create'],
            'categories.view' => ['categories.create'],
            'units.view' => ['units.create'],
            'warehouses.view' => ['warehouses.create'],
            'opening_stock.manage' => ['items.create', 'warehouses.create'],
            'stock.vouchers.view' => ['items.view', 'items.create'],
            'sales.pos' => ['sales.invoices.create', 'sales.invoices.view'],
        ];
    }

    /**
     * @return array<int, string>
     */
    public static function expand(string $permissionCode): array
    {
        $codes = [$permissionCode];
        foreach (self::aliases()[$permissionCode] ?? [] as $alias) {
            $codes[] = $alias;
        }
        return array_values(array_unique($codes));
    }

    /**
     * @return array<int, string>
     */
    public static function seededCodes(): array
    {
        return array_map(static fn(array $row): string => $row[0], self::definitions());
    }
}
