<?php

declare(strict_types=1);

namespace App\Modules\Tenants\Services;

class TenantRoleService
{
    public function __construct(
        private readonly TenantService $tenantService,
        private readonly TenantMembershipService $membershipService
    ) {
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    public function roleMatrix(): array
    {
        return [
            [
                'key' => 'tenant_admin',
                'label' => 'Tenant-Admin',
                'scope' => 'Gesamter Tenant',
                'priority' => 'Vollzugriff',
                'rights' => [
                    'Mitglieder, Rollen und Einladungen verwalten',
                    'Content, FAQ, Surveys und Support steuern',
                    'Buchungen, Einzahlungen und Korrekturen freigeben',
                    'Tenant-Einstellungen und Vier-Augen-Optionen konfigurieren',
                ],
                'delegation' => 'Kann finance_admin, support_contact und survey_manager vergeben oder entziehen.',
                'delegable_roles' => $this->membershipService->delegableRoles(),
                'can_delegate' => true,
                'tenant_wide_toggle' => true,
                'notes' => 'Ein Tenant-Admin hat im Tenant Vollzugriff und koordiniert die fachlichen Spezialrollen.',
            ],
            [
                'key' => 'finance_admin',
                'label' => 'finance_admin',
                'scope' => 'Buchungen und Einzahlungen',
                'priority' => 'Spezialrolle',
                'rights' => [
                    'Einzahlungen erfassen und stornieren',
                    'Buchungen und Striche im Ledger prüfen',
                    'Korrekturen an Verantwortliche melden',
                ],
                'delegation' => 'Wird vom Tenant-Admin vergeben. Keine weitere Delegation.',
                'delegable_roles' => [],
                'can_delegate' => false,
                'tenant_wide_toggle' => true,
                'notes' => 'Stornierungen bleiben an den Verantwortlichen gebunden.',
            ],
            [
                'key' => 'support_contact',
                'label' => 'support_contact',
                'scope' => 'Support und Routing',
                'priority' => 'Spezialrolle',
                'rights' => [
                    'Supportvorgänge lesen, routen und abschliessen',
                    'Mitglieder bei fachlichen Rueckfragen begleiten',
                    'Statuswechsel und Antworten dokumentieren',
                ],
                'delegation' => 'Wird vom Tenant-Admin vergeben. Keine weitere Delegation.',
                'delegable_roles' => [],
                'can_delegate' => false,
                'tenant_wide_toggle' => true,
                'notes' => 'Ideal fuer fachliche Ansprechpartner im Tenant.',
            ],
            [
                'key' => 'survey_manager',
                'label' => 'survey_manager',
                'scope' => 'Umfragen und Freigaben',
                'priority' => 'Spezialrolle',
                'rights' => [
                    'Umfragen entwerfen und bearbeiten',
                    'Freigaben und Snapshots auslösen',
                    'Mitgliederansichten kontrollieren',
                ],
                'delegation' => 'Wird vom Tenant-Admin vergeben. Keine weitere Delegation.',
                'delegable_roles' => [],
                'can_delegate' => false,
                'tenant_wide_toggle' => true,
                'notes' => 'Trennt Entwurf und Veröffentlichung sauber.',
            ],
            [
                'key' => 'member',
                'label' => 'Mitglied',
                'scope' => 'Eigener Tenant-Kontext',
                'priority' => 'Standard',
                'rights' => [
                    'Eigene Buchungen und Kontostand einsehen',
                    'Freigegebene Inhalte und Snapshots lesen',
                    'Support anstossen und Rückfragen stellen',
                ],
                'delegation' => 'Keine Delegation.',
                'delegable_roles' => [],
                'can_delegate' => false,
                'tenant_wide_toggle' => false,
                'notes' => 'Lesend und auf den eigenen Kontext beschränkt.',
            ],
        ];
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    public function delegationRules(): array
    {
        return [
            [
                'from' => 'platform_admin',
                'to' => 'tenant_admin',
                'rule' => 'Initiale Freischaltung und Notfall-Override',
                'approval' => 'immer',
                'note' => 'Plattform-Admins legen den ersten Tenant-Admin an und sichern den Betriebszugang.',
            ],
            [
                'from' => 'tenant_admin',
                'to' => 'finance_admin',
                'rule' => 'Buchungskorrekturen und Einzahlungen',
                'approval' => 'tenantweit konfigurierbar',
                'note' => 'Vier-Augen-Freigabe kann pro Tenant aktiviert oder deaktiviert werden.',
            ],
            [
                'from' => 'tenant_admin',
                'to' => 'support_contact',
                'rule' => 'Supportvorgänge und Routing',
                'approval' => 'tenantweit konfigurierbar',
                'note' => 'Sorgt für eine klare, fachliche Bearbeitung von Vorgängen.',
            ],
            [
                'from' => 'tenant_admin',
                'to' => 'survey_manager',
                'rule' => 'Umfragen und Snapshot-Freigaben',
                'approval' => 'tenantweit konfigurierbar',
                'note' => 'Trennt Erstellung, Prüfung und Veröffentlichung sauber.',
            ],
        ];
    }

    /**
     * @return array<string, mixed>
     */
    public function roleOverview(?string $tenantId = null): array
    {
        $tenant = $this->resolveTenant($tenantId);
        $roles = $this->roleMatrix();

        return [
            'tenant' => $tenant,
            'metrics' => [
                [
                    'label' => 'Rollensätze',
                    'value' => (string) count($roles),
                    'detail' => 'Ein lesbarer Rollenkatalog fuer Tenant-Admins und Betreiber.',
                ],
                [
                    'label' => 'Spezialrollen',
                    'value' => (string) count($this->membershipService->specialRoles()),
                    'detail' => 'finance_admin, support_contact und survey_manager sind separat steuerbar.',
                ],
                [
                    'label' => 'Tenant-Admin',
                    'value' => 'Vollzugriff',
                    'detail' => 'Tenant-Admins duerfen alle fachlichen Bereiche verwalten.',
                ],
                [
                    'label' => 'Delegation',
                    'value' => 'Konfigurierbar',
                    'detail' => 'Vier-Augen-Freigaben koennen pro Tenant aktiviert oder deaktiviert werden.',
                ],
            ],
            'roles' => $roles,
            'delegation_rules' => $this->delegationRules(),
            'tenant_snapshots' => $this->tenantSnapshots(),
            'permission_groups' => [
                [
                    'title' => 'Fachliche Kernrechte',
                    'items' => [
                        'Mitglieder',
                        'Buchungen',
                        'Einzahlungen',
                        'Content',
                        'Support',
                        'Surveys',
                    ],
                ],
                [
                    'title' => 'Betriebliche Rechte',
                    'items' => [
                        'Tenant-Einstellungen',
                        'Branding',
                        'Freigaben',
                        'Delegation',
                        'Vier-Augen-Regeln',
                    ],
                ],
            ],
            'notes' => [
                'Tenant-Admins behalten den Gesamtueberblick und koennen Spezialrollen im Tenant vergeben.',
                'Die Delegation ist tenantweit steuerbar und kann fuer bestimmte Aktionen mit Vier-Augen-Prinzip abgesichert werden.',
                'Wenn eine Anwendung einen Bereich noch nicht direkt abbildet, wird er als Tenant-Funktion eingerichtet.',
            ],
        ];
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    public function tenantSnapshots(): array
    {
        $snapshots = [];

        foreach ($this->tenantService->tenantPortfolio() as $tenant) {
            $snapshots[] = [
                'tenant_key' => $tenant['tenant_key'],
                'name' => $tenant['name'],
                'status' => $tenant['status'],
                'admin_count' => $tenant['admin_count'],
                'special_roles' => $tenant['tenant_key'] === 'finance-hub'
                    ? ['tenant_admin']
                    : ['tenant_admin', 'finance_admin', 'support_contact'],
                'delegation_state' => $tenant['tenant_key'] === 'finance-hub'
                    ? 'Vier-Augen-Prinzip aktiv'
                    : 'Tenant-Admin delegiert Spezialrollen',
                'primary_contact' => $tenant['primary_contact'],
            ];
        }

        return $snapshots;
    }

    /**
     * @return array<string, mixed>
     */
    private function resolveTenant(?string $tenantId): array
    {
        if ($tenantId !== null && $tenantId !== '') {
            $tenant = $this->tenantService->findTenantById($tenantId);

            if ($tenant !== null) {
                return $tenant;
            }

            $tenant = $this->tenantService->findTenantByKey($tenantId);

            if ($tenant !== null) {
                return $tenant;
            }
        }

        $fallback = $this->tenantService->findTenantByKey('berlin');

        if ($fallback !== null) {
            return $fallback;
        }

        return $this->tenantService->tenantPortfolio()[0];
    }
}
