<?php
/**
 * Users Controller
 * Gerencia CRUD de usuários admin
 *
 * OTIMIZADO: Removidas queries N+1 e checks de schema repetitivos
 */

namespace Controllers;

use Core\Request;
use Core\Response;
use Middleware\Auth;

class UsersController
{
    /**
     * GET /users - Listar todos os usuários (apenas super admin)
     * OTIMIZADO: Uma única query com LEFT JOIN para permissões
     */
    public static function index(): void
    {
        Auth::requireSuperAdmin();

        $pdo = getDBConnection();
        $siteId = (int)Request::get('site_id', 0);

        // Query otimizada: busca usuários e permissões em uma única query usando GROUP_CONCAT
        $sql = "
            SELECT u.id, u.username, u.email, u.role, u.site_id, u.is_active,
                   u.last_login, u.created_at, s.name as site_name, s.domain as site_domain,
                   GROUP_CONCAT(DISTINCT p.permission) as permissions_csv
            FROM admin_users u
            LEFT JOIN sites s ON s.id = u.site_id
            LEFT JOIN site_user_permissions p ON p.user_id = u.id
        ";

        if ($siteId) {
            $sql .= " WHERE u.site_id = ?";
            $sql .= " GROUP BY u.id ORDER BY u.created_at DESC";
            $stmt = $pdo->prepare($sql);
            $stmt->execute([$siteId]);
        } else {
            $sql .= " GROUP BY u.id ORDER BY u.role, u.created_at DESC";
            $stmt = $pdo->query($sql);
        }

        $users = $stmt->fetchAll();

        // Processar permissões do CSV para array
        foreach ($users as &$user) {
            if (!empty($user['permissions_csv'])) {
                $user['permissions'] = explode(',', $user['permissions_csv']);
            } elseif (empty($user['site_id'])) {
                $user['permissions'] = ['all']; // Super admin tem todas
            } else {
                $user['permissions'] = [];
            }
            unset($user['permissions_csv']);
        }

        Response::success($users);
    }

    /**
     * POST /users - Criar novo usuário (apenas super admin)
     * OTIMIZADO: Removidos checks de schema desnecessários
     */
    public static function create(): void
    {
        Auth::requireSuperAdmin();

        $username = trim(Request::input('username', ''));
        $email = trim(Request::input('email', ''));
        $password = Request::input('password', '');
        $role = Request::input('role', 'admin');
        $siteId = Request::input('site_id');
        $permissions = Request::input('permissions', []);

        // Validações
        if (!$username || strlen($username) < 3) {
            Response::error('Username deve ter pelo menos 3 caracteres', 400);
        }

        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            Response::error('Email inválido', 400);
        }

        if (!$password || strlen($password) < 6) {
            Response::error('Senha deve ter pelo menos 6 caracteres', 400);
        }

        // Normalizar role
        if ($role === 'site_admin') {
            $role = 'admin';
        }
        if (!in_array($role, ['super_admin', 'admin', 'viewer'])) {
            $role = 'admin';
        }

        // Super admin não pode ter site_id
        if ($role === 'super_admin') {
            $siteId = null;
        } else {
            $siteId = $siteId ? (int)$siteId : null;
        }

        $pdo = getDBConnection();

        // Verificar duplicatas
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM admin_users WHERE username = ? OR email = ?");
        $stmt->execute([$username, $email]);
        if ($stmt->fetchColumn() > 0) {
            Response::error('Username ou email já existem', 400);
        }

        // Criar usuário
        $passwordHash = password_hash($password, PASSWORD_DEFAULT);
        $stmt = $pdo->prepare("
            INSERT INTO admin_users (username, email, password_hash, role, site_id, is_active)
            VALUES (?, ?, ?, ?, ?, 1)
        ");
        $stmt->execute([$username, $email, $passwordHash, $role, $siteId]);

        $userId = $pdo->lastInsertId();

        // Adicionar permissões (batch insert para performance)
        if ($siteId && !empty($permissions)) {
            $values = [];
            $params = [];
            foreach ($permissions as $perm) {
                $values[] = "(?, ?, ?)";
                $params[] = $userId;
                $params[] = $siteId;
                $params[] = $perm;
            }
            if ($values) {
                $sql = "INSERT INTO site_user_permissions (user_id, site_id, permission) VALUES " . implode(',', $values);
                $pdo->prepare($sql)->execute($params);
            }
        }

        logAudit('user_created', $siteId, "User: {$username}, Role: {$role}", Request::ip());

        Response::success([
            'id' => $userId,
            'username' => $username,
            'email' => $email,
            'role' => $role,
            'site_id' => $siteId
        ], 'Usuário criado com sucesso');
    }

    /**
     * GET /user?id={id} - Obter usuário específico
     * OTIMIZADO: Query única com GROUP_CONCAT para permissões
     */
    public static function show(): void
    {
        Auth::requireSuperAdmin();

        $userId = (int)Request::get('id', 0);

        if (!$userId) {
            Response::error('User ID required', 400);
        }

        $pdo = getDBConnection();
        $stmt = $pdo->prepare("
            SELECT u.id, u.username, u.email, u.role, u.site_id, u.is_active,
                   u.last_login, u.created_at, s.name as site_name,
                   GROUP_CONCAT(DISTINCT p.permission) as permissions_csv
            FROM admin_users u
            LEFT JOIN sites s ON s.id = u.site_id
            LEFT JOIN site_user_permissions p ON p.user_id = u.id
            WHERE u.id = ?
            GROUP BY u.id
        ");
        $stmt->execute([$userId]);
        $user = $stmt->fetch();

        if (!$user) {
            Response::notFound('User not found');
        }

        // Converter permissões de CSV para array
        if (!empty($user['permissions_csv'])) {
            $user['permissions'] = explode(',', $user['permissions_csv']);
        } elseif (empty($user['site_id'])) {
            $user['permissions'] = ['all'];
        } else {
            $user['permissions'] = [];
        }
        unset($user['permissions_csv']);

        Response::success($user);
    }

    /**
     * PUT /user?id={id} - Atualizar usuário
     * OTIMIZADO: Removido check de schema, batch insert para permissões
     */
    public static function update(): void
    {
        $currentUser = Auth::requireSuperAdmin();

        $userId = (int)Request::get('id', 0);

        if (!$userId) {
            Response::error('User ID required', 400);
        }

        // Não permitir editar o próprio usuário super admin principal
        if ($userId === 1 && $currentUser['id'] !== 1) {
            Response::forbidden('Cannot edit primary super admin');
        }

        $pdo = getDBConnection();
        $updates = [];
        $params = [];

        $email = Request::input('email');
        if ($email !== null) {
            if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
                Response::error('Email inválido', 400);
            }
            $updates[] = "email = ?";
            $params[] = $email;
        }

        $role = Request::input('role');
        if ($role !== null) {
            $updates[] = "role = ?";
            $params[] = $role;
        }

        $siteIdInput = Request::input('site_id');
        if ($siteIdInput !== null) {
            $updates[] = "site_id = ?";
            $params[] = $siteIdInput ?: null;
        }

        $isActive = Request::input('is_active');
        if ($isActive !== null) {
            $updates[] = "is_active = ?";
            $params[] = $isActive ? 1 : 0;
        }

        $password = Request::input('password');
        if ($password !== null && !empty($password)) {
            if (strlen($password) < 6) {
                Response::error('Senha deve ter pelo menos 6 caracteres', 400);
            }
            $updates[] = "password_hash = ?";
            $params[] = password_hash($password, PASSWORD_DEFAULT);
        }

        if (!empty($updates)) {
            $params[] = $userId;
            $sql = "UPDATE admin_users SET " . implode(', ', $updates) . ", updated_at = NOW() WHERE id = ?";
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
        }

        // Atualizar permissões
        $permissions = Request::input('permissions');
        if ($permissions !== null) {
            // Obter site_id do usuário
            $stmt = $pdo->prepare("SELECT site_id FROM admin_users WHERE id = ?");
            $stmt->execute([$userId]);
            $userSiteId = $stmt->fetchColumn();

            // Remover permissões antigas
            $pdo->prepare("DELETE FROM site_user_permissions WHERE user_id = ?")->execute([$userId]);

            // Adicionar novas (batch insert)
            if (!empty($permissions) && $userSiteId) {
                $values = [];
                $insertParams = [];
                foreach ($permissions as $perm) {
                    $values[] = "(?, ?, ?)";
                    $insertParams[] = $userId;
                    $insertParams[] = $userSiteId;
                    $insertParams[] = $perm;
                }
                $sql = "INSERT INTO site_user_permissions (user_id, site_id, permission) VALUES " . implode(',', $values);
                $pdo->prepare($sql)->execute($insertParams);
            }
        }

        logAudit('user_updated', null, "User ID: {$userId}", Request::ip());

        Response::success(null, 'Usuário atualizado');
    }

    /**
     * DELETE /user?id={id} - Excluir usuário
     */
    public static function delete(): void
    {
        $currentUser = Auth::requireSuperAdmin();

        $userId = (int)Request::get('id', 0);

        if (!$userId) {
            Response::error('User ID required', 400);
        }

        // Não permitir excluir o próprio usuário ou o super admin principal
        if ($userId === $currentUser['id']) {
            Response::forbidden('Não é possível excluir seu próprio usuário');
        }

        if ($userId === 1) {
            Response::forbidden('Não é possível excluir o super admin principal');
        }

        $pdo = getDBConnection();
        $pdo->prepare("DELETE FROM admin_users WHERE id = ?")->execute([$userId]);

        logAudit('user_deleted', null, "User ID: {$userId}", Request::ip());

        Response::success(null, 'Usuário excluído');
    }

    /**
     * GET /site-users?site_id={id} - Usuários de um site específico
     * OTIMIZADO: Query única com GROUP_CONCAT para permissões
     */
    public static function bySite(): void
    {
        $siteId = (int)Request::get('site_id', 0);

        if (!$siteId) {
            Response::error('Site ID required', 400);
        }

        Auth::requireSuperAdmin();

        $pdo = getDBConnection();
        $stmt = $pdo->prepare("
            SELECT u.id, u.username, u.email, u.role, u.is_active, u.last_login, u.created_at,
                   GROUP_CONCAT(DISTINCT p.permission) as permissions_csv
            FROM admin_users u
            LEFT JOIN site_user_permissions p ON p.user_id = u.id
            WHERE u.site_id = ?
            GROUP BY u.id
            ORDER BY u.created_at DESC
        ");
        $stmt->execute([$siteId]);
        $users = $stmt->fetchAll();

        // Processar permissões do CSV para array
        foreach ($users as &$user) {
            if (!empty($user['permissions_csv'])) {
                $user['permissions'] = explode(',', $user['permissions_csv']);
            } else {
                $user['permissions'] = [];
            }
            unset($user['permissions_csv']);
        }

        Response::success($users);
    }
}
