<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;
use Inertia\Inertia;
use Inertia\Response;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;

class AuthenticatedSessionController extends Controller
{
    /**
     * Show the login page.
     */
    public function create(Request $request): Response
    {
        return Inertia::render('auth/login', [
            'canResetPassword' => Route::has('password.request'),
            'status' => $request->session()->get('status'),
        ]);
    }

    /**
     * Handle an incoming authentication request.
     */
    public function store(LoginRequest $request): SymfonyResponse
    {
        try {
            $request->authenticate();
        } catch (\Illuminate\Validation\ValidationException $e) {
            $request->session()->flash('error', __('auth.login_failed'));

            return redirect()->route('login')->withErrors($e->errors());
        }

        Log::info('Login attempt', ['login' => $request->login, 'authenticated' => Auth::check()]);

        $request->session()->regenerate();
        $request->session()->flash('success', __('auth.login_success'));

        $user = Auth::user();
        if ($user && $user->email_verified_at === null) {
            $intended = $request->session()->get('url.intended');
            $intended = is_string($intended) ? trim($intended) : null;

            if ($this->isVerificationLink($intended)) {
                $request->session()->forget('url.intended');

                return Inertia::location($intended);
            }

            return Inertia::location(route('verification.notice'));
        }

        $intended = $this->resolveIntended($request);
        if ($intended !== null) {
            $this->rememberTenantAdminTarget($request, $intended);

            return Inertia::location($intended);
        }

        $returnTo = $this->resolveReturnTo($request);
        if ($returnTo !== null) {
            $this->rememberTenantAdminTarget($request, $returnTo);

            return Inertia::location($returnTo);
        }

        $default = $this->defaultAdminPath();
        $this->rememberTenantAdminTarget($request, $default);

        return Inertia::location($default);
    }

    /**
     * Destroy an authenticated session.
     */
    public function destroy(Request $request): RedirectResponse
    {
        Auth::guard('web')->logout();

        $request->session()->invalidate();
        $request->session()->regenerateToken();

        return redirect('/');
    }

    private function resolveReturnTo(Request $request): ?string
    {
        $encoded = $request->string('return_to')->trim();

        if ($encoded === '') {
            return null;
        }

        return $this->normalizeTenantAdminTarget(
            $this->decodeReturnTo($encoded, $request),
            $request
        );
    }

    private function resolveIntended(Request $request): ?string
    {
        $intended = $request->session()->pull('url.intended');

        if (! is_string($intended)) {
            return null;
        }

        $trimmed = trim($intended);
        if ($trimmed === '') {
            return null;
        }

        return $this->normalizeTenantAdminTarget(
            $this->decodeReturnTo($trimmed, $request),
            $request
        );
    }

    private function isVerificationLink(?string $target): bool
    {
        if (! is_string($target) || trim($target) === '') {
            return false;
        }

        $path = trim($target);

        if (str_starts_with($path, '/verify-email/')) {
            return true;
        }

        $parsed = parse_url($path);

        if ($parsed === false) {
            return false;
        }

        $path = $parsed['path'] ?? '';

        return $path !== '' && str_starts_with($path, '/verify-email/');
    }

    private function decodeReturnTo(string $value, Request $request): ?string
    {
        $candidate = $this->decodeBase64Url($value) ?? $value;
        $candidate = trim($candidate);

        if ($candidate === '') {
            return null;
        }

        if (str_starts_with($candidate, '/')) {
            return $candidate;
        }

        $targetHost = parse_url($candidate, PHP_URL_HOST);
        $scheme = parse_url($candidate, PHP_URL_SCHEME);

        if (! $scheme || ! $targetHost) {
            return null;
        }

        $appHost = parse_url($request->getSchemeAndHttpHost(), PHP_URL_HOST);

        if ($appHost && ! Str::endsWith($targetHost, $appHost)) {
            return null;
        }

        return $candidate;
    }

    private function defaultAdminPath(): string
    {
        $user = Auth::user();

        // Block users with 'user' role - redirect to package selection
        if ($user && $user->role === 'user') {
            return '/packages';
        }

        // Super admins go to Filament superadmin panel
        if ($user && $user->isSuperAdmin()) {
            return '/super-admin';
        }

        // Tenant admins go to their PWA dashboard
        if ($user && $user->role === 'tenant_admin') {
            return '/event-admin/dashboard';
        }

        // Fallback: redirect to packages (for users with no role)
        return '/packages';
    }

    private function normalizeTenantAdminTarget(?string $target, Request $request): ?string
    {
        $user = Auth::user();

        if (! $user || $user->role !== 'tenant_admin') {
            return $target;
        }

        if ($target === null || $target === '') {
            return '/event-admin/dashboard';
        }

        $parsed = parse_url($target);
        $path = $target;
        $hasScheme = false;

        if ($parsed !== false) {
            $hasScheme = isset($parsed['scheme']);
            $host = $parsed['host'] ?? null;
            $scheme = $parsed['scheme'] ?? null;
            $requestHost = parse_url($request->getSchemeAndHttpHost(), PHP_URL_HOST);

            if ($scheme && $host && $requestHost && ! Str::endsWith($host, $requestHost)) {
                return '/event-admin/dashboard';
            }

            if (isset($parsed['path'])) {
                $path = $parsed['path'];
                if (isset($parsed['query'])) {
                    $path .= '?'.$parsed['query'];
                }
                if (isset($parsed['fragment'])) {
                    $path .= '#'.$parsed['fragment'];
                }
            }
        }

        if (! str_starts_with($path, '/')) {
            $path = '/'.$path;
        }

        if (str_starts_with($path, '/event-admin')) {
            return $hasScheme ? $target : $path;
        }

        return '/event-admin/dashboard';
    }

    private function decodeBase64Url(string $value): ?string
    {
        if ($value === '') {
            return null;
        }

        $padded = str_pad($value, strlen($value) + ((4 - (strlen($value) % 4)) % 4), '=');
        $normalized = strtr($padded, '-_', '+/');
        $decoded = base64_decode($normalized, true);

        if ($decoded === false) {
            return null;
        }

        return $decoded;
    }

    private function rememberTenantAdminTarget(Request $request, ?string $target): void
    {
        $user = Auth::user();

        if (! $user || $user->role !== 'tenant_admin') {
            return;
        }

        if (! is_string($target) || $target === '') {
            return;
        }

        $normalized = $this->normalizeTenantAdminTarget($target, $request);

        if (! is_string($normalized) || $normalized === '') {
            return;
        }

        $path = $this->extractTenantAdminPath($normalized);

        if ($path === null) {
            return;
        }

        $request->session()->put('tenant_admin.return_to', $path);
    }

    private function extractTenantAdminPath(string $target): ?string
    {
        $value = trim($target);

        if ($value === '') {
            return null;
        }

        if (str_starts_with($value, '/event-admin')) {
            return $value;
        }

        $parsed = parse_url($value);

        if ($parsed === false) {
            return null;
        }

        $path = $parsed['path'] ?? '';

        if ($path === '' || ! str_starts_with($path, '/event-admin')) {
            return null;
        }

        if (isset($parsed['query'])) {
            $path .= '?'.$parsed['query'];
        }

        if (isset($parsed['fragment'])) {
            $path .= '#'.$parsed['fragment'];
        }

        return $path;
    }
}
