<?php

namespace App\Controllers;

use App\Models\User;
use App\Models\Role;
use App\Services\Database;

class AdminController extends BaseController
{
    private $userModel;
    private $roleModel;

    public function __construct()
    {
        parent::__construct();
        $this->userModel = new User();
        $this->roleModel = new Role();
    }

    public function index()
    {
        $this->requireAuth();
        $this->requireRole(['super_admin', 'admin']);
        
        $db = Database::getInstance();
        
        $statsData = [
            'total_users' => $db->query("SELECT COUNT(*) as count FROM users")->fetch()['count'],
            'active_users' => $db->query("SELECT COUNT(*) as count FROM users WHERE is_active = 1")->fetch()['count'],
            'total_roles' => $db->query("SELECT COUNT(*) as count FROM roles")->fetch()['count'],
            'recent_logins' => $db->query("
                SELECT COUNT(*) as count 
                FROM users 
                WHERE last_login >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
            ")->fetch()['count']
        ];

        $this->render('admin/index', [
            'stats' => $statsData
        ]);
    }

    public function users()
    {
        $this->requireAuth();
        $this->requireRole(['super_admin', 'admin']);

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $this->handleUserAction();
            return;
        }

        $db = Database::getInstance();

        $users = $db->fetchAll("
            SELECT u.*, r.name as role_name, r.display_name as role_display_name, 
                   r.is_admin
            FROM users u 
            LEFT JOIN roles r ON u.role_id = r.id 
            ORDER BY u.created_at DESC
        ", []);

        $roles = $db->fetchAll("
            SELECT *, 
                   CASE WHEN name IN ('super_admin', 'admin') THEN 1 ELSE 0 END as is_system
            FROM roles 
            ORDER BY display_name
        ", []);

        $this->render('admin/users', [
            'users' => $users,
            'roles' => $roles,
            'current_page' => 'users'
        ]);
    }

    public function roles()
    {
        $this->requireAuth();
        $this->requireRole(['super_admin', 'admin']);

        // Manejar peticiones AJAX GET
        if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['action'])) {
            $this->handleRolesGetAction();
            return;
        }

        // Manejar peticiones POST
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $this->handleRolesPostAction();
            return;
        }

        // Mostrar vista normal
        $db = Database::getInstance();
        $roles = $db->fetchAll("
            SELECT *, 
                   CASE WHEN name IN ('super_admin', 'admin') THEN 1 ELSE 0 END as is_system
            FROM roles 
            ORDER BY display_name
        ", []);

        $this->render('admin/roles', [
            'roles' => $roles,
            'current_page' => 'roles'
        ]);
    }

    public function teams()
    {
        $this->requireAuth();
        $this->requireRole(['super_admin', 'admin']);

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $this->handleTeamAction();
            return;
        }

        $db = Database::getInstance();
        $teams = $db->fetchAll("SELECT * FROM teams ORDER BY name", []);
        
        // Obtener miembros de cada equipo
        foreach ($teams as &$team) {
            $team['members'] = $db->fetchAll("
                SELECT tm.id as member_id, tm.is_leader, u.id, u.first_name, u.last_name, u.email, r.display_name as role_name
                FROM team_members tm
                JOIN users u ON tm.user_id = u.id
                LEFT JOIN roles r ON u.role_id = r.id
                WHERE tm.team_id = ?
                ORDER BY tm.is_leader DESC, u.first_name
            ", [$team['id']]);
        }
        
        // Obtener usuarios disponibles (activos)
        $users = $db->fetchAll("
            SELECT u.id, u.first_name, u.last_name, u.email, r.display_name as role_name
            FROM users u
            LEFT JOIN roles r ON u.role_id = r.id
            WHERE u.is_active = 1
            ORDER BY u.first_name, u.last_name
        ", []);
        
        $this->render('admin/teams', [
            'teams' => $teams,
            'users' => $users,
            'current_page' => 'teams'
        ]);
    }

    private function handleTeamAction()
    {
        header('Content-Type: application/json');
        try {
            $csrfToken = $_POST['csrf_token'] ?? '';
            if (!$this->validateCsrfToken($csrfToken)) {
                throw new \Exception('Token CSRF inválido');
            }
            
            $action = $_POST['action'] ?? '';
            $db = Database::getInstance();

            switch ($action) {
                case 'add_member':
                    $teamId = $_POST['team_id'] ?? '';
                    $userId = $_POST['user_id'] ?? '';
                    $isLeader = isset($_POST['is_leader']) && $_POST['is_leader'] === '1' ? 1 : 0;

                    if (empty($teamId) || empty($userId)) {
                        throw new \Exception('Equipo y usuario requeridos');
                    }

                    // Verificar si ya es miembro
                    $existing = $db->fetchOne("SELECT id FROM team_members WHERE team_id = ? AND user_id = ?", [$teamId, $userId]);
                    if ($existing) {
                        throw new \Exception('El usuario ya es miembro de este equipo');
                    }

                    $db->query("INSERT INTO team_members (team_id, user_id, is_leader, joined_at) VALUES (?, ?, ?, ?)", [
                        $teamId,
                        $userId,
                        $isLeader,
                        date('Y-m-d H:i:s')
                    ]);
                    
                    echo json_encode(['success' => true, 'message' => 'Miembro agregado correctamente']);
                    break;

                case 'remove_member':
                    $memberId = $_POST['member_id'] ?? '';

                    if (empty($memberId)) {
                        throw new \Exception('ID de miembro requerido');
                    }

                    $db->query("DELETE FROM team_members WHERE id = ?", [$memberId]);
                    echo json_encode(['success' => true, 'message' => 'Miembro eliminado correctamente']);
                    break;

                case 'toggle_leader':
                    $memberId = $_POST['member_id'] ?? '';
                    $isLeader = isset($_POST['is_leader']) && $_POST['is_leader'] === '1' ? 1 : 0;

                    if (empty($memberId)) {
                        throw new \Exception('ID de miembro requerido');
                    }

                    $db->query("UPDATE team_members SET is_leader = ? WHERE id = ?", [$isLeader, $memberId]);
                    echo json_encode(['success' => true, 'message' => 'Líder actualizado correctamente']);
                    break;

                default:
                    throw new \Exception('Acción no válida');
            }

        } catch (\Exception $e) {
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
        }
        exit;
    }

    private function handleUserAction()
    {
        header('Content-Type: application/json');
        try {
            $csrfToken = $_POST['csrf_token'] ?? '';
            if (!$this->validateCsrfToken($csrfToken)) {
                throw new \Exception('Token CSRF inválido');
            }
            
            $action = $_POST['action'] ?? '';
            $db = Database::getInstance();

            switch ($action) {
                case 'invite_user':
                    $firstName = trim($_POST['first_name'] ?? '');
                    $lastName = trim($_POST['last_name'] ?? '');
                    $email = trim($_POST['email'] ?? '');
                    $roleId = $_POST['role_id'] ?? null;

                    if (empty($firstName) || empty($lastName) || empty($email)) {
                        throw new \Exception('Nombre, apellido y correo son requeridos');
                    }

                    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
                        throw new \Exception('Correo electrónico inválido');
                    }

                    // Verificar si el correo ya existe
                    $existing = $db->fetchOne("SELECT id FROM users WHERE email = ?", [$email]);
                    if ($existing) {
                        throw new \Exception('Ya existe un usuario con este correo electrónico');
                    }

                    // Generar username temporal desde el email (antes del @)
                    $username = strtolower(explode('@', $email)[0]);
                    // Agregar sufijo si el username ya existe
                    $baseUsername = $username;
                    $counter = 1;
                    while ($db->fetchOne("SELECT id FROM users WHERE username = ?", [$username])) {
                        $username = $baseUsername . $counter;
                        $counter++;
                    }

                    // Generar token de invitación (fallback si Keycloak falla)
                    $invitationToken = bin2hex(random_bytes(32));
                    $invitationExpiry = date('Y-m-d H:i:s', strtotime('+7 days'));

                    // Intentar sincronización con Keycloak primero
                    $keycloakId = null;
                    $keycloakUsername = null;
                    $keycloakMessage = '';
                    $keycloakSuccess = false;
                    
                    try {
                        require_once __DIR__ . '/../Services/KeycloakService.php';
                        $keycloak = new \App\Services\KeycloakService();
                        
                        if ($keycloak->isAdminApiAvailable()) {
                            $result = $keycloak->inviteUser($email, $firstName, $lastName);
                            $keycloakId = $result['keycloak_id'];
                            $keycloakUsername = $result['username'];
                            $keycloakMessage = $result['message'];
                            $keycloakSuccess = true;
                            
                            // Usuario sincronizado con Keycloak, usar su username
                            $username = $keycloakUsername;
                        }
                    } catch (\Exception $e) {
                        error_log("Keycloak integration error: " . $e->getMessage());
                        // Continuar con flujo manual
                    }

                    // Crear usuario en base de datos local
                    $db->query("INSERT INTO users (username, first_name, last_name, email, keycloak_id, role_id, is_active, invitation_token, invitation_expiry, created_at) VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?, NOW())", [
                        $username,
                        $firstName,
                        $lastName,
                        $email,
                        $keycloakId,
                        $roleId,
                        $invitationToken,
                        $invitationExpiry
                    ]);

                    if ($keycloakSuccess) {
                        // Keycloak ya envió el correo de verificación
                        echo json_encode([
                            'success' => true, 
                            'message' => $keycloakMessage
                        ]);
                    } else {
                        // Fallback: correo manual
                        $invitationLink = ($_ENV['APP_URL'] ?? 'http://localhost:8080') . '/accept-invitation?token=' . $invitationToken;
                        $emailSent = $this->sendInvitationEmail($email, $firstName, $invitationLink);

                        echo json_encode([
                            'success' => true, 
                            'message' => '⚠️ Usuario creado. ' . ($emailSent ? 'Correo enviado.' : 'Keycloak no disponible. Enlace: ' . $invitationLink)
                        ]);
                    }
                    break;

                case 'toggle_status':
                    $userId = $_POST['user_id'] ?? '';
                    $isActive = $_POST['is_active'] ?? '0';
                    
                    // Convertir 'true'/'false' string a entero 1/0
                    $isActive = ($isActive === 'true' || $isActive === '1' || $isActive === 1) ? 1 : 0;

                    if (empty($userId)) {
                        throw new \Exception('ID de usuario requerido');
                    }

                    $userData = $db->fetchOne("SELECT u.id, u.first_name, u.last_name, r.name as role_name FROM users u LEFT JOIN roles r ON u.role_id = r.id WHERE u.id = ?", [$userId]);
                    
                    if (!$userData) {
                        throw new \Exception('Usuario no encontrado');
                    }

                    if ($userData['role_name'] === 'super_admin' && !$isActive) {
                        $superAdminsCount = $db->fetchOne("SELECT COUNT(*) as count FROM users u LEFT JOIN roles r ON u.role_id = r.id WHERE r.name = 'super_admin' AND u.is_active = 1")['count'];
                        
                        if ($superAdminsCount <= 1) {
                            throw new \Exception('No se puede desactivar el último Super Admin');
                        }
                    }

                    $db->query("UPDATE users SET is_active = ? WHERE id = ?", [$isActive, $userId]);
                    echo json_encode(['success' => true, 'message' => 'Estado actualizado correctamente']);
                    break;

                case 'update_role':
                    $userId = $_POST['user_id'] ?? '';
                    $roleId = $_POST['role_id'] ?? null;

                    if (empty($userId)) {
                        throw new \Exception('ID de usuario requerido');
                    }

                    $db->query("UPDATE users SET role_id = ? WHERE id = ?", [$roleId, $userId]);
                    $message = $roleId ? 'Rol actualizado correctamente' : 'Rol eliminado correctamente';
                    echo json_encode(['success' => true, 'message' => $message]);
                    break;

                default:
                    throw new \Exception('Acción no válida');
            }

        } catch (\Exception $e) {
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
        }
        exit;
    }

    private function handleRolesGetAction()
    {
        header('Content-Type: application/json');
        
        try {
            $action = $_GET['action'] ?? '';
            $db = Database::getInstance();
            
            switch ($action) {
                case 'get':
                    $roleId = $_GET['role_id'] ?? '';
                    if (empty($roleId)) {
                        throw new \Exception('ID de rol requerido');
                    }
                    
                    $role = $db->fetchOne("SELECT * FROM roles WHERE id = ?", [$roleId]);
                    if (!$role) {
                        throw new \Exception('Rol no encontrado');
                    }
                    
                    echo json_encode(['success' => true, 'data' => $role]);
                    break;
                    
                default:
                    throw new \Exception('Acción no válida');
            }
        } catch (\Exception $e) {
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
        }
        exit;
    }

    private function handleRolesPostAction()
    {
        header('Content-Type: application/json');
        
        try {
            $this->validateCsrfToken();
            $action = $_POST['action'] ?? '';
            $db = Database::getInstance();
            
            switch ($action) {
                case 'create':
                    $name = trim($_POST['name'] ?? '');
                    $displayName = trim($_POST['display_name'] ?? '');
                    $description = trim($_POST['description'] ?? '');
                    $isAdmin = isset($_POST['is_admin']) ? 1 : 0;
                    $permissions = $_POST['permissions'] ?? '{}';
                    
                    if (empty($name) || empty($displayName)) {
                        throw new \Exception('Nombre y nombre para mostrar son requeridos');
                    }
                    
                    // Verificar que no exista
                    $exists = $db->fetchOne("SELECT id FROM roles WHERE name = ?", [$name]);
                    if ($exists) {
                        throw new \Exception('Ya existe un rol con ese nombre');
                    }
                    
                    $db->insert("INSERT INTO roles (name, display_name, description, is_admin, permissions) VALUES (?, ?, ?, ?, ?)", 
                        [$name, $displayName, $description, $isAdmin, $permissions]);
                    
                    echo json_encode(['success' => true, 'message' => 'Rol creado correctamente']);
                    break;
                    
                case 'update':
                    $roleId = $_POST['role_id'] ?? '';
                    $displayName = trim($_POST['display_name'] ?? '');
                    $description = trim($_POST['description'] ?? '');
                    $isAdmin = isset($_POST['is_admin']) ? 1 : 0;
                    $permissions = $_POST['permissions'] ?? '{}';
                    
                    if (empty($roleId) || empty($displayName)) {
                        throw new \Exception('ID y nombre para mostrar son requeridos');
                    }
                    
                    $db->query("UPDATE roles SET display_name = ?, description = ?, is_admin = ?, permissions = ? WHERE id = ?",
                        [$displayName, $description, $isAdmin, $permissions, $roleId]);
                    
                    echo json_encode(['success' => true, 'message' => 'Rol actualizado correctamente']);
                    break;
                    
                case 'delete':
                    $roleId = $_POST['role_id'] ?? '';
                    
                    if (empty($roleId)) {
                        throw new \Exception('ID de rol requerido');
                    }
                    
                    // Verificar que no sea un rol del sistema
                    $role = $db->fetchOne("SELECT name FROM roles WHERE id = ?", [$roleId]);
                    if (in_array($role['name'], ['super_admin', 'admin'])) {
                        throw new \Exception('No se puede eliminar un rol del sistema');
                    }
                    
                    // Verificar que no tenga usuarios asignados
                    $usersCount = $db->fetchOne("SELECT COUNT(*) as count FROM users WHERE role_id = ?", [$roleId])['count'];
                    if ($usersCount > 0) {
                        throw new \Exception('No se puede eliminar un rol que tiene usuarios asignados');
                    }
                    
                    $db->query("DELETE FROM roles WHERE id = ?", [$roleId]);
                    echo json_encode(['success' => true, 'message' => 'Rol eliminado correctamente']);
                    break;
                    
                default:
                    throw new \Exception('Acción no válida');
            }
        } catch (\Exception $e) {
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
        }
        exit;
    }

    /**
     * Enviar correo de invitación
     */
    private function sendInvitationEmail(string $email, string $firstName, string $invitationLink): bool
    {
        // Por ahora retorna false indicando que el correo no se envió
        // En producción, integrar con un servicio de correo real (SendGrid, AWS SES, etc.)
        // o con Keycloak para que maneje el envío de invitaciones
        
        // TODO: Implementar integración con Keycloak
        // - Crear usuario en Keycloak con email verification requerido
        // - Keycloak enviará automáticamente el correo de verificación
        // - Al confirmar, sincronizar los datos completos desde Keycloak
        
        // Ejemplo de implementación con mailer:
        /*
        $subject = "Invitación al Sistema de Gestión de Proyectos";
        $message = "
            <h2>Hola {$firstName},</h2>
            <p>Has sido invitado a unirte al Sistema de Gestión de Proyectos.</p>
            <p>Para activar tu cuenta, haz clic en el siguiente enlace:</p>
            <p><a href='{$invitationLink}'>{$invitationLink}</a></p>
            <p>Este enlace expirará en 7 días.</p>
        ";
        mail($email, $subject, $message, "From: noreply@sistema.com\r\nContent-Type: text/html");
        */
        
        return false; // Cambia a true cuando implementes el envío real
    }
}
