<?php
require_once '../config/database.php';
require_once '../app/helpers/rbac.php';
require_once '../app/helpers/alerts.php';
require_once '../app/helpers/api_security.php';
require_once '../app/helpers/audit.php';
require_once '../app/helpers/soft_delete.php';

requireApiLogin();
enforceCsrfForUnsafeRequest();

$action = $_GET['action'] ?? '';

// Profile and password actions don't require user.view
$publicActions = ['profile', 'save_profile', 'change_password'];
if (!in_array($action, $publicActions, true) && !can('user.view')) {
    echo json_encode(['status'=>'error','message'=>'Unauthorized']);
    exit;
}

switch ($action) {

case 'list':
    $search = trim((string)($_GET['search'] ?? ''));
    $where = 'u.deleted_at IS NULL';
    $params = [];
    if ($search !== '') {
        $where .= ' AND (u.name LIKE :search OR u.email LIKE :search OR u.phone LIKE :search)';
        $params['search'] = '%' . $search . '%';
    }

    $countStmt = $pdo->prepare("SELECT COUNT(*) FROM users u WHERE $where");
    $countStmt->execute($params);
    $total = (int)$countStmt->fetchColumn();

    $page = max(1, (int)($_GET['page'] ?? 1));
    $perPage = max(10, min(100, (int)($_GET['per_page'] ?? 50)));
    $offset = ($page - 1) * $perPage;

    $stmt = $pdo->prepare("
        SELECT
            u.id,
            u.name,
            u.email,
            u.phone,
            u.role_id,
            u.is_active,
            u.email_alerts_enabled,
            u.sms_alerts_enabled,
            r.name AS role_name
        FROM users u
        LEFT JOIN roles r ON r.id = u.role_id
        WHERE $where
        ORDER BY u.id ASC
        LIMIT $perPage OFFSET $offset
    ");
    $stmt->execute($params);
    $users = $stmt->fetchAll();

    echo json_encode(['data' => $users, 'total' => $total, 'page' => $page, 'total_pages' => (int)ceil($total / $perPage)]);
    break;

case 'roles':

    $stmt = $pdo->query("SELECT id, name FROM roles");
    echo json_encode(['data'=>$stmt->fetchAll()]);
    break;

case 'save':

    $id = isset($_POST['id']) ? (int)$_POST['id'] : 0;
    $isUpdate = $id > 0;

    if ($isUpdate && !can('user.edit')) {
        echo json_encode(['status' => 'error', 'message' => 'Unauthorized']);
        exit;
    }
    if (!$isUpdate && !can('user.create')) {
        echo json_encode(['status' => 'error', 'message' => 'Unauthorized']);
        exit;
    }

    $password = (string)($_POST['password'] ?? '');

    if ($isUpdate) {

        $stmt = $pdo->prepare("
            UPDATE users SET name=?, email=?, phone=?, email_alerts_enabled=?, sms_alerts_enabled=?, role_id=?, is_active=?
            WHERE id=? AND deleted_at IS NULL
        ");
        $stmt->execute([
            $_POST['name'],
            $_POST['email'],
            trim((string)($_POST['phone'] ?? '')),
            (int)($_POST['email_alerts_enabled'] ?? 1),
            (int)($_POST['sms_alerts_enabled'] ?? 1),
            $_POST['role_id'],
            $_POST['is_active'],
            $id
        ]);

        if ($password !== '') {
            validateUserPassword($password);
            $stmt = $pdo->prepare("UPDATE users SET password_hash=? WHERE id=?");
            $stmt->execute([password_hash($password, PASSWORD_BCRYPT), $id]);
        }

        audit($pdo, (int)$_SESSION['user_id'], 'update', 'user', $id, 'User updated', null, null);

    } else {

        validateUserPassword($password);
        $hash = password_hash($password, PASSWORD_BCRYPT);

        $stmt = $pdo->prepare("
            INSERT INTO users (name,email,phone,email_alerts_enabled,sms_alerts_enabled,password_hash,role_id,is_active)
            VALUES (?,?,?,?,?,?,?,?)
        ");
        $stmt->execute([
            $_POST['name'],
            $_POST['email'],
            trim((string)($_POST['phone'] ?? '')),
            (int)($_POST['email_alerts_enabled'] ?? 1),
            (int)($_POST['sms_alerts_enabled'] ?? 1),
            $hash,
            $_POST['role_id'],
            $_POST['is_active']
        ]);
        $id = (int)$pdo->lastInsertId();

        audit($pdo, (int)$_SESSION['user_id'], 'create', 'user', $id, 'User created', null, null);
    }

    echo json_encode(['status' => 'success']);
    break;

case 'delete':

    if (!can('user.delete')) {
        echo json_encode(['status'=>'error','message'=>'Unauthorized']);
        exit;
    }

    $id = (int)($_POST['id'] ?? 0);
    softDelete($pdo, 'users', $id);
    audit($pdo, (int)$_SESSION['user_id'], 'delete', 'user', $id, 'User deleted', null, null);

    echo json_encode(['status'=>'success']);
    break;

case 'restore':
    if (!can('user.edit')) {
        echo json_encode(['status' => 'error', 'message' => 'Unauthorized']);
        exit;
    }
    $id = (int)($_POST['id'] ?? 0);
    if ($id <= 0) {
        echo json_encode(['status'=>'error','message'=>'Invalid user ID']);
        exit;
    }
    restoreRecord($pdo, 'users', $id);
    audit($pdo, (int)$_SESSION['user_id'], 'restore', 'user', $id, 'User restored', null, null);
    echo json_encode(['status'=>'success']);
    break;

case 'profile':
    $userId = (int)$_SESSION['user_id'];
    $stmt = $pdo->prepare("SELECT id, name, email, phone, role_id, is_active FROM users WHERE id = ? AND deleted_at IS NULL");
    $stmt->execute([$userId]);
    $user = $stmt->fetch();
    if (!$user) {
        echo json_encode(['status'=>'error','message'=>'User not found']);
        exit;
    }
    $roleStmt = $pdo->prepare("SELECT id, name FROM roles WHERE id = ?");
    $roleStmt->execute([$user['role_id']]);
    $role = $roleStmt->fetch();
    $user['role_name'] = $role['name'] ?? '';
    echo json_encode(['status'=>'success', 'data'=>$user]);
    break;

case 'save_profile':
    $userId = (int)$_SESSION['user_id'];
    $name = trim((string)($_POST['name'] ?? ''));
    $phone = trim((string)($_POST['phone'] ?? ''));
    if ($name === '') {
        echo json_encode(['status'=>'error','message'=>'Name is required']);
        exit;
    }
    $pdo->prepare("UPDATE users SET name=?, phone=? WHERE id=?")->execute([$name, $phone, $userId]);
    $_SESSION['user_name'] = $name;
    audit($pdo, $userId, 'update', 'user', $userId, 'Profile updated', null, null);
    echo json_encode(['status'=>'success']);
    break;

case 'change_password':
    $userId = (int)$_SESSION['user_id'];
    $current = (string)($_POST['current_password'] ?? '');
    $newPass = (string)($_POST['new_password'] ?? '');
    if ($current === '' || $newPass === '') {
        echo json_encode(['status'=>'error','message'=>'All fields are required']);
        exit;
    }
    $stmt = $pdo->prepare("SELECT password_hash FROM users WHERE id = ?");
    $stmt->execute([$userId]);
    $row = $stmt->fetch();
    if (!$row || !password_verify($current, $row['password_hash'])) {
        echo json_encode(['status'=>'error','message'=>'Current password is incorrect']);
        exit;
    }
    validateUserPassword($newPass);
    $stmt = $pdo->prepare("SELECT password_hash FROM user_password_history WHERE user_id = ? ORDER BY created_at DESC LIMIT 5");
    $stmt->execute([$userId]);
    foreach ($stmt->fetchAll() as $hist) {
        if (password_verify($newPass, $hist['password_hash'])) {
            echo json_encode(['status'=>'error','message'=>'You cannot reuse a recent password']);
            exit;
        }
    }
    $stmt = $pdo->prepare("INSERT INTO user_password_history (user_id, password_hash) VALUES (?, ?)");
    $stmt->execute([$userId, $row['password_hash']]);
    $pdo->prepare("UPDATE users SET password_hash=? WHERE id=?")->execute([password_hash($newPass, PASSWORD_BCRYPT), $userId]);
    audit($pdo, $userId, 'update', 'user', $userId, 'Password changed', null, null);
    echo json_encode(['status'=>'success']);
    break;
}

function validateUserPassword(string $password): void
{
    if (strlen($password) < 8) {
        echo json_encode(['status'=>'error','message'=>'Password must be at least 8 characters']);
        exit;
    }

    if (!preg_match('/[A-Z]/', $password) || !preg_match('/[a-z]/', $password) || !preg_match('/\d/', $password) || !preg_match('/[^A-Za-z\d]/', $password)) {
        echo json_encode(['status'=>'error','message'=>'Password must include uppercase, lowercase, number, and special character']);
        exit;
    }
}
