<?php
// login.php
declare(strict_types=1);

if (session_status() !== PHP_SESSION_ACTIVE) {
    session_start();
}

require_once __DIR__ . '/db.php';

if (!function_exists('db')) {
    header('Location: index.html?e=500');
    exit;
}

/* =========================
   DB
========================= */
try {
    $pdo = db();
    if (!$pdo instanceof PDO) {
        throw new RuntimeException('db() did not return PDO');
    }

    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (Throwable $e) {
    header('Location: index.html?e=500');
    exit;
}

/* =========================
   Input
========================= */
$login = trim((string)($_POST['username'] ?? $_POST['email'] ?? $_POST['login'] ?? ''));
$password = (string)($_POST['password'] ?? '');

if ($login === '' || $password === '') {
    header('Location: index.html?e=1');
    exit;
}

/* =========================
   Helpers
========================= */
function table_exists(PDO $pdo, string $table): bool
{
    try {
        $st = $pdo->prepare('SHOW TABLES LIKE ?');
        $st->execute([$table]);
        return (bool)$st->fetchColumn();
    } catch (Throwable $e) {
        return false;
    }
}

function get_table_columns(PDO $pdo, string $table): array
{
    try {
        $cols = $pdo->query("SHOW COLUMNS FROM `$table`")->fetchAll(PDO::FETCH_COLUMN, 0);
        return is_array($cols) ? $cols : [];
    } catch (Throwable $e) {
        return [];
    }
}

function columns_exist(PDO $pdo, string $table, array $need): bool
{
    $cols = get_table_columns($pdo, $table);
    if (!$cols) {
        return false;
    }

    foreach ($need as $c) {
        if (!in_array($c, $cols, true)) {
            return false;
        }
    }

    return true;
}

function branch_name_ar_simple(int $branchId): string
{
    return match ($branchId) {
        2 => 'دبي',
        3 => 'الشارقة',
        4 => 'العين',
        default => 'أبوظبي',
    };
}

/* =========================
   Schema detection
========================= */
$userColumns = get_table_columns($pdo, 'users');

if (!$userColumns) {
    header('Location: index.html?e=500');
    exit;
}

$permCols = ['can_cases', 'can_tasks', 'can_hr', 'can_finance', 'can_reports', 'can_permissions'];

$usersHasPerms    = columns_exist($pdo, 'users', $permCols);
$usersHasProfile  = in_array('profile_id', $userColumns, true);
$usersHasName     = in_array('name', $userColumns, true);
$usersHasEmail    = in_array('email', $userColumns, true);
$usersHasStatus   = in_array('status', $userColumns, true);
$usersHasBranch   = in_array('branch_id', $userColumns, true);
$usersHasPhotoUrl = in_array('photo_url', $userColumns, true);

$profilesTableOk = table_exists($pdo, 'permission_profiles')
    && columns_exist($pdo, 'permission_profiles', array_merge(['id', 'is_active'], $permCols));

/* =========================
   Build user SELECT safely
========================= */
$select = [
    'u.id',
    'u.username',
    'u.password',
    'u.role',
];

if ($usersHasName) {
    $select[] = 'u.name';
}
if ($usersHasEmail) {
    $select[] = 'u.email';
}
if ($usersHasStatus) {
    $select[] = 'u.status';
}
if ($usersHasBranch) {
    $select[] = 'u.branch_id';
}
if ($usersHasPhotoUrl) {
    $select[] = 'u.photo_url';
}
if ($usersHasProfile) {
    $select[] = 'u.profile_id';
}
if ($usersHasPerms) {
    $select[] = 'u.can_cases';
    $select[] = 'u.can_tasks';
    $select[] = 'u.can_hr';
    $select[] = 'u.can_finance';
    $select[] = 'u.can_reports';
    $select[] = 'u.can_permissions';
}

$join = '';
if ($profilesTableOk && $usersHasProfile) {
    $select[] = 'p.can_cases AS p_can_cases';
    $select[] = 'p.can_tasks AS p_can_tasks';
    $select[] = 'p.can_hr AS p_can_hr';
    $select[] = 'p.can_finance AS p_can_finance';
    $select[] = 'p.can_reports AS p_can_reports';
    $select[] = 'p.can_permissions AS p_can_permissions';

    $join = ' LEFT JOIN permission_profiles p ON p.id = u.profile_id AND p.is_active = 1 ';
}

$where = $usersHasEmail
    ? 'WHERE u.username = ? OR u.email = ?'
    : 'WHERE u.username = ?';

/* =========================
   Fetch user
========================= */
try {
    $sql = 'SELECT ' . implode(', ', $select) . ' FROM users u ' . $join . ' ' . $where . ' LIMIT 1';
    $st = $pdo->prepare($sql);

    if ($usersHasEmail) {
        $st->execute([$login, $login]);
    } else {
        $st->execute([$login]);
    }

    $user = $st->fetch();
} catch (Throwable $e) {
    header('Location: index.html?e=500');
    exit;
}

if (!$user) {
    header('Location: index.html?e=1');
    exit;
}

/* =========================
   Status check
========================= */
$status = strtolower(trim((string)($user['status'] ?? 'active')));
$activeValues = ['active', '1', 'yes', 'on', 'enabled'];

if (!in_array($status, $activeValues, true)) {
    header('Location: index.html?e=2');
    exit;
}

/* =========================
   Password check
========================= */
$stored = (string)($user['password'] ?? '');
if ($stored === '') {
    header('Location: index.html?e=1');
    exit;
}

$storedIsHash =
    str_starts_with($stored, '$2y$') ||
    str_starts_with($stored, '$2a$') ||
    str_starts_with($stored, '$argon2');

$ok = $storedIsHash
    ? password_verify($password, $stored)
    : hash_equals($stored, $password);

if (!$ok) {
    header('Location: index.html?e=1');
    exit;
}

/* migrate plain -> hash */
if (!$storedIsHash) {
    try {
        $newHash = password_hash($password, PASSWORD_BCRYPT);
        $upd = $pdo->prepare('UPDATE users SET password = ? WHERE id = ? LIMIT 1');
        $upd->execute([$newHash, (int)$user['id']]);
    } catch (Throwable $e) {
        // لا تمنع الدخول
    }
}

/* =========================
   Success: session fixation protection
========================= */
session_regenerate_id(true);

/* =========================
   Core session data
========================= */
$userId   = (int)($user['id'] ?? 0);
$username = trim((string)($user['username'] ?? ''));
$name     = trim((string)($user['name'] ?? ''));
$email    = trim((string)($user['email'] ?? ''));
$role     = strtoupper(trim((string)($user['role'] ?? 'STAFF')));
$dbBranch = (int)($user['branch_id'] ?? 0);
$photoUrl = trim((string)($user['photo_url'] ?? ''));

$displayName = $name !== '' ? $name : ($username !== '' ? $username : 'مستخدم');
$employeeId = 0;

try {
    $empCols = get_table_columns($pdo, 'employees');

    if ($empCols) {
        if (in_array('user_id', $empCols, true)) {
            $stEmp = $pdo->prepare("SELECT id FROM employees WHERE user_id = ? LIMIT 1");
            $stEmp->execute([$userId]);
            $employeeId = (int)($stEmp->fetchColumn() ?: 0);
        } elseif (in_array('email', $empCols, true) && $email !== '') {
            $stEmp = $pdo->prepare("SELECT id FROM employees WHERE email = ? LIMIT 1");
            $stEmp->execute([$email]);
            $employeeId = (int)($stEmp->fetchColumn() ?: 0);
        } elseif (in_array('username', $empCols, true) && $username !== '') {
            $stEmp = $pdo->prepare("SELECT id FROM employees WHERE username = ? LIMIT 1");
            $stEmp->execute([$username]);
            $employeeId = (int)($stEmp->fetchColumn() ?: 0);
        }
    }
} catch (Throwable $e) {
    $employeeId = 0;
}

$_SESSION['user_id']     = $userId;
$_SESSION['employee_id'] = $employeeId;
$_SESSION['username']    = $username;
$_SESSION['name']        = $displayName;
$_SESSION['full_name']   = $displayName;
$_SESSION['email']       = $email;
$_SESSION['role']        = $role;
$_SESSION['photo_url']   = $photoUrl;
/* =========================
   Determine permissions
========================= */
$_SESSION['can_cases']       = 0;
$_SESSION['can_tasks']       = 0;
$_SESSION['can_hr']          = 0;
$_SESSION['can_finance']     = 0;
$_SESSION['can_reports']     = 0;
$_SESSION['can_permissions'] = 0;

$profileReady = $profilesTableOk
    && $usersHasProfile
    && !empty($user['profile_id'])
    && array_key_exists('p_can_cases', $user);

if ($profileReady) {
    $_SESSION['can_cases']       = (int)($user['p_can_cases'] ?? 0);
    $_SESSION['can_tasks']       = (int)($user['p_can_tasks'] ?? 0);
    $_SESSION['can_hr']          = (int)($user['p_can_hr'] ?? 0);
    $_SESSION['can_finance']     = (int)($user['p_can_finance'] ?? 0);
    $_SESSION['can_reports']     = (int)($user['p_can_reports'] ?? 0);
    $_SESSION['can_permissions'] = (int)($user['p_can_permissions'] ?? 0);
} elseif ($usersHasPerms) {
    $_SESSION['can_cases']       = (int)($user['can_cases'] ?? 0);
    $_SESSION['can_tasks']       = (int)($user['can_tasks'] ?? 0);
    $_SESSION['can_hr']          = (int)($user['can_hr'] ?? 0);
    $_SESSION['can_finance']     = (int)($user['can_finance'] ?? 0);
    $_SESSION['can_reports']     = (int)($user['can_reports'] ?? 0);
    $_SESSION['can_permissions'] = (int)($user['can_permissions'] ?? 0);
}

/* OWNER / ADMIN full permissions */
if (in_array($role, ['OWNER', 'ADMIN'], true)) {
    $_SESSION['can_cases']       = 1;
    $_SESSION['can_tasks']       = 1;
    $_SESSION['can_hr']          = 1;
    $_SESSION['can_finance']     = 1;
    $_SESSION['can_reports']     = 1;
    $_SESSION['can_permissions'] = 1;
}

/* =========================
   Branch lock rules
========================= */
if (in_array($role, ['OWNER', 'ADMIN'], true)) {
    $sidBranch = (int)($_SESSION['branch_id'] ?? 0);
    $_SESSION['branch_id'] = $sidBranch > 0 ? $sidBranch : ($dbBranch > 0 ? $dbBranch : 1);
    $_SESSION['branch_locked'] = 0;
} else {
    if ($dbBranch <= 0) {
        $_SESSION = [];
        if (ini_get('session.use_cookies')) {
            $params = session_get_cookie_params();
            setcookie(session_name(), '', time() - 42000, $params['path'], $params['domain'], (bool)$params['secure'], (bool)$params['httponly']);
        }
        session_destroy();
        header('Location: index.html?e=no_branch');
        exit;
    }

    $_SESSION['branch_id'] = $dbBranch;
    $_SESSION['branch_locked'] = 1;
}

$_SESSION['branch_name'] = branch_name_ar_simple((int)$_SESSION['branch_id']);

/* =========================
   Optional last login update
========================= */
try {
    $userCols = $userColumns;
    if (in_array('last_login_at', $userCols, true)) {
        $st = $pdo->prepare('UPDATE users SET last_login_at = NOW() WHERE id = ? LIMIT 1');
        $st->execute([$userId]);
    } elseif (in_array('last_login', $userCols, true)) {
        $st = $pdo->prepare('UPDATE users SET last_login = NOW() WHERE id = ? LIMIT 1');
        $st->execute([$userId]);
    }
} catch (Throwable $e) {
    // لا تمنع الدخول
}

/* =========================
   Go dashboard
========================= */
header('Location: dashboard.php');
exit;