<?php

require_once '../../core/config.php';
require_once '../../core/session.php';
require_once '../../core/database.php';
require_once '../../core/permissions.php';
require_once '../../services/analytics/DashboardUserAccessAdminService.php';
require_once '../../services/costs/CostAccess.php';
require_once '../../services/treasury/TreasuryAccess.php';
require_once '../../services/billing/BillingAccess.php';

require_login();
require_permission('admin.users.edit');

if (strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET')) !== 'POST') {
    http_response_code(405);
    exit('Método no permitido.');
}
csrf_require_valid_request();

$pdo = db();
$id = isset($_POST['id']) ? (int)$_POST['id'] : 0;
$name = trim((string)($_POST['name'] ?? ''));
$role = trim((string)($_POST['role'] ?? ''));
$status = trim((string)($_POST['status'] ?? ''));
$passwordRaw = (string)($_POST['password'] ?? '');
$postedPermissions = isset($_POST['permissions']) && is_array($_POST['permissions']) ? $_POST['permissions'] : array();
$postedDashboardAccess = isset($_POST['dashboard_access']) && is_array($_POST['dashboard_access']) ? $_POST['dashboard_access'] : array();
$dashboardAccessPresent = isset($_POST['dashboard_access_present']) && (string)$_POST['dashboard_access_present'] === '1';

$allowedRoles = array('admin','administracion','comercial','operaciones');
$allowedStatuses = array('active','inactive');
if ($id <= 0 || !in_array($role, $allowedRoles, true) || !in_array($status, $allowedStatuses, true)) {
    $_SESSION['admin_users_notice'] = array('type' => 'error', 'message' => 'Los datos del usuario no son válidos.');
    header('Location: /modules/admin/users.php');
    exit;
}
if ($id === current_user_id() && ($role !== 'admin' || $status !== 'active')) {
    $_SESSION['admin_users_notice'] = array('type' => 'error', 'message' => 'No puedes quitar tu propio acceso administrativo ni desactivar tu cuenta.');
    header('Location: /modules/admin/users.php');
    exit;
}

$allowedModulePermissions = array();
foreach (get_system_modules(true) as $key => $module) $allowedModulePermissions[] = 'module.' . $key;
$allowedModulePermissions = array_merge($allowedModulePermissions, array_keys(cost_permission_catalog()), array_keys(treasury_permission_catalog()), array_keys(billing_permission_catalog()));
$permissions = array_values(array_unique(array_intersect(array_map('strval', $postedPermissions), $allowedModulePermissions)));
$permissions = billing_expand_user_permissions($permissions);
if (array_intersect($permissions, array('costs.edit','costs.approve','costs.payroll.view','costs.payroll.edit','costs.close','costs.product.view','costs.product.edit','costs.product.approve','costs.margin.view')) && !in_array('costs.view', $permissions, true)) $permissions[] = 'costs.view';
if (in_array('costs.payroll.edit', $permissions, true) && !in_array('costs.payroll.view', $permissions, true)) $permissions[] = 'costs.payroll.view';
if (array_intersect($permissions, array('costs.product.edit','costs.product.approve')) && !in_array('costs.product.view', $permissions, true)) $permissions[] = 'costs.product.view';
if (array_intersect($permissions, array('treasury.edit','treasury.reconcile','treasury.scenarios')) && !in_array('treasury.view', $permissions, true)) $permissions[] = 'treasury.view';
$permissionsJson = json_encode($permissions, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$isActive = $status === 'active' ? 1 : 0;

try {
    $pdo->beginTransaction();
    $stmt = $pdo->prepare('SELECT role FROM users WHERE id=? FOR UPDATE');
    $stmt->execute(array($id));
    $previousRole = $stmt->fetchColumn();
    if ($previousRole === false) throw new RuntimeException('Usuario no encontrado.');

    if ($passwordRaw !== '') {
        $stmt = $pdo->prepare('UPDATE users SET name=?,role=?,status=?,is_active=?,password=?,module_permissions=? WHERE id=?');
        $stmt->execute(array($name, $role, $status, $isActive, password_hash($passwordRaw, PASSWORD_DEFAULT), $permissionsJson, $id));
    } else {
        $stmt = $pdo->prepare('UPDATE users SET name=?,role=?,status=?,is_active=?,module_permissions=? WHERE id=?');
        $stmt->execute(array($name, $role, $status, $isActive, $permissionsJson, $id));
    }

    if ($dashboardAccessPresent) {
        $dashboardAccess = new DashboardUserAccessAdminService($pdo);
        $dashboardAccess->saveAccessMatrix($id, $role, $postedDashboardAccess, current_user_id(), (string)$previousRole);
    }
    $pdo->commit();
    unset($_SESSION['user']['permissions']);
    $_SESSION['admin_users_notice'] = array('type' => 'success', 'message' => 'Usuario y permisos de módulos, dashboards, costos, tesorería y facturación actualizados correctamente.');
} catch (Throwable $e) {
    if ($pdo->inTransaction()) $pdo->rollBack();
    error_log('admin user update error: ' . $e->getMessage());
    $_SESSION['admin_users_notice'] = array('type' => 'error', 'message' => 'No fue posible actualizar el usuario.');
}

header('Location: /modules/admin/users.php');
exit;
