<?php

namespace App\Support;

use App\Models\User;

class TenantPermissionCatalog
{
    public static function groups(): array
    {
        return [
            'Core' => [
                'dashboard.view' => ['label' => 'View dashboard', 'description' => 'See tenant dashboard metrics, alerts, and tenant website link.'],
                'customers.view' => ['label' => 'View members', 'description' => 'Open member records, KYC, guarantor details, and member history.'],
                'customers.manage' => ['label' => 'Manage members', 'description' => 'Create and update member records.'],
            ],
            'Products' => [
                'savings.view' => ['label' => 'View savings', 'description' => 'View savings accounts, balances, statements, and receipts.'],
                'savings.manage' => ['label' => 'Manage savings', 'description' => 'Create savings accounts and record deposits or withdrawals.'],
                'savings.approve' => ['label' => 'Approve savings deposits', 'description' => 'Approve or reject pending savings deposit transactions.'],
                'loans.view' => ['label' => 'View loans', 'description' => 'View loan applications, loan statements, schedules, and guarantors.'],
                'loans.create' => ['label' => 'Create loans', 'description' => 'Create loan applications for members.'],
                'loans.approve' => ['label' => 'Approve or reject loans', 'description' => 'Approve, reject, and review pending loan applications.'],
                'loans.disburse' => ['label' => 'Disburse loans', 'description' => 'Disburse approved loans and create accounting entries.'],
                'repayments.view' => ['label' => 'View repayments', 'description' => 'Open the quick repayments page and repayment history.'],
                'repayments.record' => ['label' => 'Record repayments', 'description' => 'Collect loan repayments and generate repayment receipts.'],
                'repayments.approve' => ['label' => 'Approve repayments', 'description' => 'Approve or reject pending loan repayments before they update loan balances.'],
                'transfers.view' => ['label' => 'View transfers', 'description' => 'View internal member transfers and bank transfer requests.'],
                'transfers.manage' => ['label' => 'Manage transfers', 'description' => 'Initiate or manage member transfer records.'],
                'transfers.approve' => ['label' => 'Approve transfers', 'description' => 'Approve, reject, or cancel pending member transfer requests.'],
                'loan_products.manage' => ['label' => 'Manage loan products', 'description' => 'Create, edit, or remove loan products and interest settings.'],
                'investments.view' => ['label' => 'View investments', 'description' => 'Access investment products and member investment tracking.'],
                'investments.manage' => ['label' => 'Manage investments', 'description' => 'Create investment products, open investment accounts, and post investment transactions.'],
                'investments.approve' => ['label' => 'Approve investment deposits', 'description' => 'Approve or reject pending investment deposit transactions.'],
            ],
            'Finance' => [
                'expenses.view' => ['label' => 'View expenses', 'description' => 'View expense reports, categories, and expense history.'],
                'expenses.create' => ['label' => 'Create expenses', 'description' => 'Record tenant operating expenses.'],
                'expenses.approve' => ['label' => 'Approve expenses', 'description' => 'Approve or reject pending expense requests and post approved expenses to accounting.'],
                'accounting.view' => ['label' => 'View accounting', 'description' => 'View income, trial balance, profit and loss, balance sheet, cashflow, and journals.'],
                'accounting.accounts.manage' => ['label' => 'Manage chart of accounts', 'description' => 'Create and edit ledger accounts used by journals and reports.'],
                'accounting.income.create' => ['label' => 'Record income', 'description' => 'Record non-loan income in accounting.'],
                'accounting.journals.create' => ['label' => 'Create journals', 'description' => 'Post manual debit and credit journal entries.'],
                'billing.view' => ['label' => 'View billing', 'description' => 'View subscription, invoices, payment history, and renewal status.'],
                'billing.manage' => ['label' => 'Manage billing', 'description' => 'Submit payments, start gateway payment, and update auto-renewal.'],
                'communication_units.manage' => ['label' => 'Manage message units', 'description' => 'Buy SMS and WhatsApp units and review wallet usage.'],
                'bill_payments.view' => ['label' => 'View bill payments', 'description' => 'View airtime, data, electricity, cable TV, and internet payment records.'],
                'bill_payments.manage' => ['label' => 'Manage bill payments', 'description' => 'Record bill payments and update bill payment status.'],
            ],
            'Reports' => [
                'reports.view' => ['label' => 'View reports', 'description' => 'Open tenant reports, defaulters report, and repayment performance.'],
                'reports.export' => ['label' => 'Export reports', 'description' => 'Download PDF reports.'],
            ],
            'Communication' => [
                'notifications.view' => ['label' => 'View alerts', 'description' => 'View system notifications and mark alerts as read.'],
                'notifications.send' => ['label' => 'Send notifications', 'description' => 'Send member email, SMS, portal, WhatsApp, and custom contact messages.'],
                'bulk_sms.send' => ['label' => 'Send custom messages', 'description' => 'Send custom SMS, WhatsApp, or email campaigns from Notifications.'],
                'support.view' => ['label' => 'Use support', 'description' => 'Open and submit tenant support tickets.'],
            ],
            'Administration' => [
                'audit_trail.view' => ['label' => 'View audit trail', 'description' => 'Review staff, member, login, and system activity logs for the tenant.'],
                'settings.manage' => ['label' => 'Manage company settings', 'description' => 'Edit company profile, tenant portal slug, notifications, and payment gateways.'],
                'data_imports.manage' => ['label' => 'Import and sync data', 'description' => 'Import legacy data and sync offline or online installations.'],
                'branches.manage' => ['label' => 'Manage branches', 'description' => 'Create and update tenant branches.'],
                'staff.manage' => ['label' => 'Manage staff', 'description' => 'Create staff accounts and assign role profiles.'],
                'role_profiles.manage' => ['label' => 'Manage role profiles', 'description' => 'Create custom permission profiles and control staff access.'],
            ],
        ];
    }

    public static function all(): array
    {
        return collect(self::groups())
            ->flatMap(fn (array $permissions) => array_keys($permissions))
            ->values()
            ->all();
    }

    public static function defaultForRole(string $role): array
    {
        return match ($role) {
            User::ROLE_TENANT_ADMIN => self::all(),
            User::ROLE_MANAGER => self::all(),
            User::ROLE_LOAN_OFFICER => [
                'dashboard.view',
                'customers.view',
                'customers.manage',
                'savings.view',
                'savings.manage',
                'loans.view',
                'loans.create',
                'repayments.view',
                'repayments.record',
                'transfers.view',
                'transfers.manage',
                'investments.view',
                'investments.manage',
                'reports.view',
                'notifications.view',
                'support.view',
            ],
            User::ROLE_ACCOUNTANT => [
                'dashboard.view',
                'customers.view',
                'savings.view',
                'loans.view',
                'repayments.view',
                'repayments.record',
                'repayments.approve',
                'transfers.view',
                'transfers.approve',
                'expenses.view',
                'expenses.create',
                'accounting.view',
                'accounting.accounts.manage',
                'accounting.income.create',
                'accounting.journals.create',
                'billing.view',
                'billing.manage',
                'communication_units.manage',
                'bill_payments.view',
                'bill_payments.manage',
                'reports.view',
                'reports.export',
                'notifications.view',
                'support.view',
            ],
            default => [],
        };
    }

    public static function defaultProfiles(): array
    {
        return [
            User::ROLE_TENANT_ADMIN => [
                'name' => 'Tenant Admin',
                'description' => 'Full owner access to all tenant modules and settings.',
            ],
            User::ROLE_MANAGER => [
                'name' => 'Manager',
                'description' => 'Broad operational access for branch or company managers.',
            ],
            User::ROLE_LOAN_OFFICER => [
                'name' => 'Loan Officer',
                'description' => 'Member, savings, loans, repayments, reports, and support access.',
            ],
            User::ROLE_ACCOUNTANT => [
                'name' => 'Accountant',
                'description' => 'Finance, accounting, repayments, billing, bill payment, and report access.',
            ],
        ];
    }

    public static function permissionsForRoute(?string $routeName): array
    {
        return array_values((array) self::permissionForRoute($routeName));
    }

    public static function permissionForRoute(?string $routeName): string|array|null
    {
        if (! $routeName) {
            return null;
        }

        $exact = [
            'tenant.dashboard' => 'dashboard.view',
            'tenant.customers.index' => 'customers.view',
            'tenant.customers.show' => 'customers.view',
            'tenant.savings.index' => 'savings.view',
            'tenant.savings.show' => 'savings.view',
            'tenant.savings.approve' => 'savings.approve',
            'tenant.savings.reject' => 'savings.approve',
            'tenant.savings.transactions.store' => 'savings.manage',
            'tenant.savings.transactions.approve' => 'savings.approve',
            'tenant.savings.transactions.reject' => 'savings.approve',
            'tenant.savings.transactions.cancel' => 'savings.approve',
            'tenant.savings.transactions.receipt' => 'savings.view',
            'tenant.deposits.index' => 'savings.view',
            'tenant.deposits.store' => 'savings.manage',
            'tenant.withdrawals.index' => 'savings.view',
            'tenant.transfers.index' => 'transfers.view',
            'tenant.transfers.approve' => 'transfers.approve',
            'tenant.transfers.reject' => 'transfers.approve',
            'tenant.transfers.cancel' => 'transfers.approve',
            'tenant.savings-products.store' => 'savings.manage',
            'tenant.savings-products.update' => 'savings.manage',
            'tenant.savings-products.destroy' => 'savings.manage',
            'tenant.investments.index' => 'investments.view',
            'tenant.investments.show' => 'investments.view',
            'tenant.investments.accounts.store' => 'investments.manage',
            'tenant.investments.approve' => 'investments.approve',
            'tenant.investments.reject' => 'investments.approve',
            'tenant.investments.transactions.store' => 'investments.manage',
            'tenant.investments.transactions.approve' => 'investments.approve',
            'tenant.investments.transactions.reject' => 'investments.approve',
            'tenant.investments.transactions.cancel' => 'investments.approve',
            'tenant.investment-products.store' => 'investments.manage',
            'tenant.investment-products.update' => 'investments.manage',
            'tenant.investment-products.destroy' => 'investments.manage',
            'tenant.repayments.index' => 'repayments.view',
            'tenant.loans.index' => 'loans.view',
            'tenant.loans.show' => 'loans.view',
            'tenant.loans.create' => 'loans.create',
            'tenant.loans.store' => 'loans.create',
            'tenant.loans.edit' => 'loans.create',
            'tenant.loans.update' => 'loans.create',
            'tenant.loans.approve' => 'loans.approve',
            'tenant.loans.reject' => 'loans.approve',
            'tenant.loans.disburse' => 'loans.disburse',
            'tenant.loans.schedule.regenerate' => 'loans.approve',
            'tenant.loans.reschedule' => 'loans.approve',
            'tenant.loans.payments.store' => 'repayments.record',
            'tenant.loan-payments.approve' => 'repayments.approve',
            'tenant.loan-payments.reject' => 'repayments.approve',
            'tenant.loan-payments.cancel' => 'repayments.approve',
            'tenant.loan-payments.receipt' => 'repayments.view',
            'tenant.accounting.index' => 'accounting.view',
            'tenant.accounting.accounts.store' => 'accounting.accounts.manage',
            'tenant.accounting.accounts.update' => 'accounting.accounts.manage',
            'tenant.accounting.income.store' => 'accounting.income.create',
            'tenant.accounting.income.cancel' => 'accounting.income.create',
            'tenant.accounting.journals.store' => 'accounting.journals.create',
            'tenant.expenses.index' => 'expenses.view',
            'tenant.expenses.store' => 'expenses.create',
            'tenant.expenses.approve' => 'expenses.approve',
            'tenant.expenses.reject' => 'expenses.approve',
            'tenant.expenses.cancel' => 'expenses.approve',
            'tenant.expenses.categories.store' => 'expenses.create',
            'tenant.expenses.categories.update' => 'expenses.create',
            'tenant.reports.index' => 'reports.view',
            'tenant.reports.pdf' => 'reports.export',
            'tenant.billing.index' => 'billing.view',
            'tenant.billing.payments.store' => 'billing.manage',
            'tenant.billing.gateway.start' => 'billing.manage',
            'tenant.billing.gateway.callback' => 'billing.manage',
            'tenant.billing.auto-renewal.update' => 'billing.manage',
            'tenant.communication-units.index' => 'communication_units.manage',
            'tenant.communication-units.manual.store' => 'communication_units.manage',
            'tenant.communication-units.gateway.start' => 'communication_units.manage',
            'tenant.communication-units.gateway.callback' => 'communication_units.manage',
            'tenant.vtu-wallet.index' => 'bill_payments.view',
            'tenant.vtu-wallet.manual.store' => 'bill_payments.manage',
            'tenant.vtu-wallet.gateway.start' => 'bill_payments.manage',
            'tenant.vtu-wallet.gateway.callback' => 'bill_payments.manage',
            'tenant.bill-payments.index' => 'bill_payments.view',
            'tenant.bill-payments.store' => 'bill_payments.manage',
            'tenant.bill-payments.status' => 'bill_payments.manage',
            'tenant.bill-payments.cancel' => 'bill_payments.manage',
            'tenant.bulk-sms.index' => 'bulk_sms.send',
            'tenant.bulk-sms.store' => 'bulk_sms.send',
            'tenant.audit-trail.index' => 'audit_trail.view',
            'tenant.settings.edit' => 'settings.manage',
            'tenant.settings.update' => 'settings.manage',
            'tenant.data-imports.index' => 'data_imports.manage',
            'tenant.data-imports.store' => 'data_imports.manage',
            'tenant.data-imports.template' => 'data_imports.manage',
            'tenant.sync.index' => 'data_imports.manage',
            'tenant.sync.clients.store' => 'data_imports.manage',
            'tenant.sync.export' => 'data_imports.manage',
            'tenant.sync.import' => 'data_imports.manage',
            'tenant.sync.remote' => 'data_imports.manage',
            'tenant.sync.auto' => 'data_imports.manage',
            'tenant.sync.run' => 'data_imports.manage',
            'tenant.sync.push' => 'data_imports.manage',
            'tenant.sync.pull' => 'data_imports.manage',
            'tenant.customer-notifications.index' => ['notifications.send', 'bulk_sms.send'],
            'tenant.customer-notifications.store' => ['notifications.send', 'bulk_sms.send'],
            'tenant.customer-notifications.resend-failed' => ['notifications.send', 'bulk_sms.send'],
            'tenant.support.index' => 'support.view',
            'tenant.support.store' => 'support.view',
            'tenant.notifications.index' => 'notifications.view',
            'tenant.notifications.read' => 'notifications.view',
        ];

        if (isset($exact[$routeName])) {
            return $exact[$routeName];
        }

        foreach ([
            'tenant.customers.' => 'customers.manage',
            'tenant.staff.' => 'staff.manage',
            'tenant.role-profiles.' => 'role_profiles.manage',
            'tenant.branches.' => 'branches.manage',
            'tenant.loan-products.' => 'loan_products.manage',
        ] as $prefix => $permission) {
            if (str_starts_with($routeName, $prefix)) {
                return $permission;
            }
        }

        return null;
    }
}
