<?php

namespace App\Controllers;

use App\Services\KeycloakService;
use App\Models\User;
use App\Middleware\AuthMiddleware;

/**
 * Controlador de autenticación
 */
class AuthController
{
    private $keycloakService;
    private $userModel;
    private $authMiddleware;

    public function __construct()
    {
        $this->keycloakService = new KeycloakService();
        $this->userModel = new User();
        $this->authMiddleware = new AuthMiddleware();
    }

    /**
     * Mostrar página de login
     */
    public function showLogin(): void
    {
        // Si ya está autenticado, redirigir según su estado
        if ($this->authMiddleware->isAuthenticated()) {
            if ($this->authMiddleware->hasRole()) {
                header('Location: /dashboard');
            } else {
                header('Location: /pending');
            }
            exit;
        }

        require_once __DIR__ . '/../../views/auth/login.php';
    }

    /**
     * Procesar login tradicional (sin Keycloak)
     */
    public function login(): void
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            header('Location: /login');
            exit;
        }

        $username = $_POST['username'] ?? '';
        $password = $_POST['password'] ?? '';

        // Validación básica
        if (empty($username) || empty($password)) {
            $_SESSION['error'] = 'Usuario y contraseña son requeridos';
            header('Location: /login');
            exit;
        }

        // Autenticación simple (para desarrollo)
        $user = $this->authenticateUser($username, $password);
        
        if ($user) {
            // Iniciar sesión
            session_regenerate_id(true);
            $_SESSION['user'] = $user;
            $_SESSION['authenticated'] = true;
            $_SESSION['last_activity'] = time();

            $_SESSION['success'] = 'Bienvenido al sistema';
            
            // Redirigir según el rol
            if ($user['role_name'] === 'admin' || $user['is_admin']) {
                header('Location: /dashboard');
            } else {
                header('Location: /dashboard');
            }
            exit;
        } else {
            $_SESSION['error'] = 'Credenciales inválidas';
            header('Location: /login');
            exit;
        }
    }

    /**
     * Autenticar usuario (método simple para desarrollo)
     */
    private function authenticateUser(string $username, string $password): ?array
    {
        // Usuarios de prueba para desarrollo
        $testUsers = [
            'admin' => [
                'password' => 'admin123',
                'user' => [
                    'id' => 1,
                    'username' => 'admin',
                    'first_name' => 'Administrador',
                    'last_name' => 'Sistema',
                    'email' => 'admin@uai.edu.pe',
                    'role_name' => 'admin',
                    'role_display_name' => 'Administrador',
                    'is_admin' => true,
                    'has_role' => true
                ]
            ],
            'usuario' => [
                'password' => 'user123',
                'user' => [
                    'id' => 2,
                    'username' => 'usuario',
                    'first_name' => 'Usuario',
                    'last_name' => 'Estándar',
                    'email' => 'usuario@uai.edu.pe',
                    'role_name' => 'user',
                    'role_display_name' => 'Usuario',
                    'is_admin' => false,
                    'has_role' => true
                ]
            ]
        ];

        if (isset($testUsers[$username])) {
            $userConfig = $testUsers[$username];
            if ($password === $userConfig['password']) {
                return $userConfig['user'];
            }
        }

        // En el futuro, aquí se verificaría con la base de datos
        return null;
    }

    /**
     * Redirigir a Keycloak para autenticación
     */
    public function redirectToKeycloak(): void
    {
        $state = bin2hex(random_bytes(16));
        $_SESSION['auth_state'] = $state;
        
        $authUrl = $this->keycloakService->getAuthUrl($state);
        header("Location: $authUrl");
        exit;
    }

    /**
     * Callback de autenticación desde Keycloak
     */
    public function handleCallback(): void
    {
        $code = $_GET['code'] ?? null;
        $state = $_GET['state'] ?? null;
        $error = $_GET['error'] ?? null;

        // Verificar si hay error en la autenticación
        if ($error) {
            $_SESSION['error'] = 'Error en la autenticación: ' . ($_GET['error_description'] ?? $error);
            header('Location: /login');
            exit;
        }

        // Verificar código y state
        if (!$code || !$state || $state !== ($_SESSION['auth_state'] ?? '')) {
            $_SESSION['error'] = 'Parámetros de autenticación inválidos';
            header('Location: /login');
            exit;
        }

        try {
            // Intercambiar código por token
            $tokenResponse = $this->keycloakService->exchangeCodeForToken($code);
            if (!$tokenResponse) {
                error_log('Keycloak token exchange failed for code: ' . substr($code, 0, 10) . '...');
                throw new \Exception('No se pudo obtener el token de acceso');
            }

            // Obtener información del usuario
            $userInfo = $this->keycloakService->getUserInfo($tokenResponse['access_token']);
            if (!$userInfo) {
                throw new \Exception('No se pudo obtener la información del usuario');
            }

            // Sincronizar usuario con base de datos
            $user = $this->keycloakService->syncUser($userInfo);
            if (!$user) {
                throw new \Exception('Error al sincronizar usuario');
            }

            // Guardar información en sesión
            $_SESSION['user'] = $user;
            $_SESSION['access_token'] = $tokenResponse['access_token'];
            $_SESSION['refresh_token'] = $tokenResponse['refresh_token'] ?? null;

            // Registrar login
            $this->keycloakService->logAuthAction($user['id'], 'login');
            $this->userModel->updateLastLogin($user['id']);

            // Limpiar estado temporal
            unset($_SESSION['auth_state']);
            unset($_SESSION['error']);

            // Redirigir según el estado del usuario
            if ($this->keycloakService->userHasAccess($user)) {
                header('Location: /dashboard');
            } else {
                header('Location: /pending');
            }

        } catch (\Exception $e) {
            error_log('Auth callback error: ' . $e->getMessage());
            
            // Mostrar error más específico en desarrollo
            if ($_ENV['APP_DEBUG'] ?? false) {
                $_SESSION['error'] = 'Error de autenticación: ' . $e->getMessage();
            } else {
                $_SESSION['error'] = 'Error durante el proceso de autenticación. Por favor, contacte al administrador.';
            }
            
            header('Location: /login');
        }

        exit;
    }

    /**
     * Página de espera para usuarios sin rol
     */
    public function showPending(): void
    {
        $this->authMiddleware->requireAuth();

        $user = $this->authMiddleware->getCurrentUser();
        
        // Si ya tiene rol, redirigir al dashboard
        if ($this->authMiddleware->hasRole()) {
            header('Location: /dashboard');
            exit;
        }

        require_once __DIR__ . '/../../views/auth/pending.php';
    }

    /**
     * Verificar estado del rol (AJAX)
     */
    public function checkRoleStatus(): void
    {
        header('Content-Type: application/json');
        header('Cache-Control: no-cache, must-revalidate');

        try {
            if (!$this->authMiddleware->isAuthenticated()) {
                echo json_encode([
                    'error' => 'No autenticado',
                    'redirect' => '/login'
                ]);
                exit;
            }

            $user = $this->authMiddleware->getCurrentUser();
            
            if (!$user) {
                echo json_encode([
                    'error' => 'Usuario no encontrado en sesión',
                    'redirect' => '/login'
                ]);
                exit;
            }
            
            // Refrescar datos del usuario desde la base de datos
            $updatedUser = $this->userModel->findById($user['id']);
            
            if (!$updatedUser) {
                echo json_encode([
                    'error' => 'Usuario no encontrado en base de datos',
                    'redirect' => '/login'
                ]);
                exit;
            }

            // Actualizar sesión con datos frescos
            $_SESSION['user'] = $updatedUser;
            
            // Forzar regeneración de sesión para asegurar que los cambios se guarden
            session_write_close();
            session_start();
            $_SESSION['user'] = $updatedUser;
            
            $hasRole = $this->keycloakService->userHasAccess($updatedUser);
            
            echo json_encode([
                'success' => true,
                'has_role' => $hasRole,
                'role_name' => $updatedUser['role_display_name'] ?? null,
                'is_active' => (bool) $updatedUser['is_active'],
                'role_id' => $updatedUser['role_id'],
                'user_info' => [
                    'name' => $updatedUser['first_name'] . ' ' . $updatedUser['last_name'],
                    'email' => $updatedUser['email']
                ],
                'debug' => [
                    'session_updated' => true,
                    'timestamp' => time()
                ]
            ]);

        } catch (\Exception $e) {
            error_log('checkRoleStatus Error: ' . $e->getMessage());
            echo json_encode([
                'error' => 'Error interno del servidor',
                'message' => ($_ENV['APP_DEBUG'] ?? false) ? $e->getMessage() : 'Error interno'
            ]);
        }

        exit;
    }

    /**
     * Logout del sistema
     */
    public function logout(): void
    {
        $user = $this->authMiddleware->getCurrentUser();
        
        if ($user) {
            $this->keycloakService->logAuthAction($user['id'], 'logout');
        }

        // Limpiar sesión local
        $this->authMiddleware->logout();

        // Construir URL de logout de Keycloak
        $redirectUri = $_ENV['APP_URL'] . '/login';
        $keycloakLogoutUrl = $this->keycloakService->getLogoutUrl($redirectUri);

        // Redirigir a logout de Keycloak
        header("Location: $keycloakLogoutUrl");
        exit;
    }

    /**
     * Obtener información del usuario actual (AJAX)
     */
    public function getCurrentUserInfo(): void
    {
        header('Content-Type: application/json');

        if (!$this->authMiddleware->isAuthenticated()) {
            echo json_encode(['error' => 'No autenticado']);
            exit;
        }

        $user = $this->authMiddleware->getCurrentUser();
        
        // Remover información sensible
        unset($user['keycloak_id']);
        
        echo json_encode([
            'user' => $user,
            'permissions' => json_decode($user['permissions'] ?? '[]', true)
        ]);

        exit;
    }
}