<?php

declare(strict_types=1);

namespace App\Modules\Identity\Services;

use App\Modules\Identity\Support\IdentityPolicy;
use App\Modules\Identity\Support\OidcProviderConfig;
use App\Modules\Identity\Support\RoleMatrix;
use App\Modules\Tenants\Services\TenantService;

class AuthService
{
    public function __construct(
        private readonly TenantService $tenantService,
        private readonly IdentityPolicy $identityPolicy = new IdentityPolicy(),
        private readonly RoleMatrix $roleMatrix = new RoleMatrix(),
        private readonly OidcProviderService $oidcProviderService = new OidcProviderService()
    ) {
    }

    public function availableProviders(): array
    {
        return [
            'password' => [
                'label' => 'Lokale Systemanmeldung',
                'type' => 'password',
                'required' => true,
                'description' => 'Pflichtweg fuer lokale Konten und Fallback bei externen Ausfaellen.',
            ],
            'adfs_oidc' => [
                'label' => 'ADFS / OIDC',
                'type' => 'oidc',
                'required' => false,
                'description' => 'Zusatzoption fuer angebundene Identitaetsprovider.',
            ],
        ];
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    public function configuredOidcProviders(): array
    {
        return array_map(
            static fn (OidcProviderConfig $provider): array => $provider->toArray(),
            $this->oidcProviderService->configuredProviders()
        );
    }

    public function identityPolicy(): array
    {
        return $this->identityPolicy->toArray();
    }

    public function roleMatrix(): array
    {
        return $this->roleMatrix->toArray();
    }

    /**
     * @return array<string, mixed>
     */
    public function centralLoginPreview(): array
    {
        $singleEmail = 'mia@berlin.example';
        $multipleEmail = 'leitung@kaffeeliste.example';
        $unknownEmail = 'extern@example.org';

        return [
            'single' => [
                'email' => $singleEmail,
                'status' => 'redirect-tenant',
                'matches' => $this->tenantService->lookupTenantsByEmail($singleEmail),
                'message' => 'Bei genau einem Treffer wird direkt in den zugeordneten Tenant weitergeleitet. Dort folgt dann die lokale Anmeldung oder ADFS/OIDC.',
            ],
            'multiple' => [
                'email' => $multipleEmail,
                'status' => 'select-tenant',
                'matches' => $this->tenantService->lookupTenantsByEmail($multipleEmail),
                'message' => 'Bei mehreren Trefferkonten erscheint zuerst eine Tenant-Auswahl fuer denselben Mitarbeiter. Der E-Mail-Abgleich bleibt dabei die gemeinsame Grundlage.',
            ],
            'unknown' => [
                'email' => $unknownEmail,
                'status' => 'request-tenant',
                'matches' => [],
                'message' => 'Unbekannte Mail-Adressen werden nicht ins Leere geleitet, sondern klar auf Tenant- oder Admin-Kontakt gefuehrt. Lokale Anmeldung bleibt weiterhin moeglich.',
            ],
        ];
    }

    public function attemptLogin(array $payload): array
    {
        $email = strtolower(trim((string) ($payload['email'] ?? '')));
        $matches = $this->tenantService->lookupTenantsByEmail($email);

        if (count($matches) === 1) {
            $tenant = $matches[0];

            return [
                'status' => 'redirect-tenant',
                'email' => $email,
                'tenant' => $tenant,
                'redirect_to' => 'https://' . $tenant['domain'] . '/login',
                'login_modes' => ['password', 'adfs_oidc'],
                'policy' => $this->identityPolicy(),
            ];
        }

        if (count($matches) > 1) {
            return [
                'status' => 'select-tenant',
                'email' => $email,
                'tenants' => $matches,
                'login_modes' => ['password', 'adfs_oidc'],
                'policy' => $this->identityPolicy(),
            ];
        }

        return [
            'status' => 'request-tenant',
            'email' => $email !== '' ? $email : null,
            'login_modes' => ['password', 'adfs_oidc'],
            'policy' => $this->identityPolicy(),
        ];
    }
}
