<?php
require_once __DIR__ . '/../../includes/bootstrap.php';
require_login();

$pageTitle = 'Users';

if (file_exists(__DIR__ . '/../../includes/permission_check.php')) {
    require_once __DIR__ . '/../../includes/permission_check.php';
    if (function_exists('require_permission')) {
        require_permission($pdo, 'role_permissions', 'view');
    }
}

if (!function_exists('h')) {
    function h($value): string { return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); }
}
if (!function_exists('users_flash')) {
    function users_flash(string $type, string $message): void {
        $_SESSION['users_flash'][] = ['type' => $type, 'message' => $message];
    }
}
if (!function_exists('users_get_flash')) {
    function users_get_flash(): array {
        $items = $_SESSION['users_flash'] ?? [];
        unset($_SESSION['users_flash']);
        return $items;
    }
}
if (!function_exists('users_table_exists')) {
    function users_table_exists(PDO $pdo, string $table): bool {
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name=:t");
        $stmt->execute([':t' => $table]);
        return (int)$stmt->fetchColumn() > 0;
    }
}
if (!function_exists('users_column_exists')) {
    function users_column_exists(PDO $pdo, string $table, string $column): bool {
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name=:t AND column_name=:c");
        $stmt->execute([':t' => $table, ':c' => $column]);
        return (int)$stmt->fetchColumn() > 0;
    }
}

if (!function_exists('users_status_columns')) {
    function users_status_columns(PDO $pdo): array {
        $cols = [];
        foreach (['active', 'is_active', 'status', 'user_status'] as $col) {
            if (users_column_exists($pdo, 'users', $col)) {
                $cols[] = $col;
            }
        }
        return $cols ?: ['active'];
    }
}
if (!function_exists('users_active_select_expr')) {
    function users_active_select_expr(PDO $pdo): string {
        if (users_column_exists($pdo, 'users', 'active')) return "COALESCE(active,1)";
        if (users_column_exists($pdo, 'users', 'is_active')) return "COALESCE(is_active,1)";
        if (users_column_exists($pdo, 'users', 'status')) return "COALESCE(status,1)";
        if (users_column_exists($pdo, 'users', 'user_status')) return "COALESCE(user_status,1)";
        return "1";
    }
}
if (!function_exists('users_is_active_value')) {
    function users_is_active_value(array $user): int {
        foreach (['active', 'is_active', 'status', 'user_status'] as $col) {
            if (array_key_exists($col, $user)) {
                return (int)$user[$col] === 1 ? 1 : 0;
            }
        }
        return 1;
    }
}
if (!function_exists('users_status_update_data')) {
    function users_status_update_data(PDO $pdo, int $active): array {
        $active = $active === 1 ? 1 : 0;
        $data = [];
        foreach (users_status_columns($pdo) as $col) {
            if (users_column_exists($pdo, 'users', $col)) {
                $data[$col] = $active;
            }
        }
        return $data ?: ['active' => $active];
    }
}
if (!function_exists('role_key_from_user_role')) {
    function role_key_from_user_role(int $userRole): string {
        $map = [
            1 => 'super_admin',
            2 => 'admin',
            3 => 'manager',
            4 => 'frontdesk',
            5 => 'cashier',
            6 => 'stores',
            7 => 'accounts',
            8 => 'housekeeping',
            9 => 'owner',
            10 => 'user',
        ];
        return $map[$userRole] ?? 'user';
    }
}
if (!function_exists('legacy_user_role_from_role_key')) {
    function legacy_user_role_from_role_key(string $roleKey): int {
        $map = [
            'super_admin' => 1,
            'admin' => 2,
            'manager' => 3,
            'frontdesk' => 4,
            'cashier' => 5,
            'stores' => 6,
            'accounts' => 7,
            'housekeeping' => 8,
            'owner' => 9,
            'user' => 10,
        ];
        return $map[$roleKey] ?? 10;
    }
}
if (!function_exists('role_label_from_user_role')) {
    function role_label_from_user_role(int $userRole): string {
        $map = [
            1 => 'Super Admin',
            2 => 'Admin',
            3 => 'Manager',
            4 => 'Front Desk',
            5 => 'Cashier',
            6 => 'Stores',
            7 => 'Accounts',
            8 => 'Housekeeping',
            9 => 'Owner',
            10 => 'User',
        ];
        return $map[$userRole] ?? 'User';
    }
}
if (!function_exists('role_options')) {
    function role_options(PDO $pdo): array {
        if (!users_table_exists($pdo, 'roles')) {
            return [
                'super_admin' => 'Super Admin',
                'admin' => 'Admin',
                'manager' => 'Manager',
                'frontdesk' => 'Front Desk',
                'cashier' => 'Cashier',
                'stores' => 'Stores',
                'accounts' => 'Accounts',
                'housekeeping' => 'Housekeeping',
                'owner' => 'Owner',
                'user' => 'User',
            ];
        }

        $stmt = $pdo->query("
            SELECT role_key, role_name
            FROM roles
            WHERE is_active = 1
            ORDER BY is_system DESC, role_name ASC
        ");

        $roles = [];
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
            $key = strtolower(trim((string)$row['role_key']));
            if ($key !== '') {
                $roles[$key] = (string)$row['role_name'];
            }
        }

        return $roles ?: ['user' => 'User'];
    }
}
if (!function_exists('role_label_from_role_key')) {
    function role_label_from_role_key(PDO $pdo, string $roleKey): string {
        $roleKey = strtolower(trim($roleKey));
        static $cache = [];

        if ($roleKey === '') return 'User';

        if (!isset($cache[$roleKey])) {
            $roles = role_options($pdo);
            $cache[$roleKey] = $roles[$roleKey] ?? ucwords(str_replace('_', ' ', $roleKey));
        }

        return $cache[$roleKey];
    }
}
if (!function_exists('ensure_role_permission_tables')) {
    function ensure_role_permission_tables(PDO $pdo): void {
        $pdo->exec("CREATE TABLE IF NOT EXISTS roles (
            id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
            role_key VARCHAR(80) NOT NULL,
            role_name VARCHAR(120) NOT NULL,
            description TEXT NULL,
            is_system TINYINT(1) NOT NULL DEFAULT 0,
            is_active TINYINT(1) NOT NULL DEFAULT 1,
            created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
            updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            UNIQUE KEY uq_role_key (role_key)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

        $pdo->exec("CREATE TABLE IF NOT EXISTS role_permissions (
            id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
            role_key VARCHAR(80) NOT NULL,
            permission_key VARCHAR(120) NOT NULL,
            can_view TINYINT(1) NOT NULL DEFAULT 0,
            can_create TINYINT(1) NOT NULL DEFAULT 0,
            can_edit TINYINT(1) NOT NULL DEFAULT 0,
            can_delete TINYINT(1) NOT NULL DEFAULT 0,
            can_approve TINYINT(1) NOT NULL DEFAULT 0,
            created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
            updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            UNIQUE KEY uq_role_permission (role_key, permission_key),
            INDEX idx_role_key (role_key),
            INDEX idx_permission_key (permission_key)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

        $roles = [
            ['super_admin','Super Admin','Full system access'],
            ['admin','Admin','System administrator'],
            ['manager','Manager','Operational manager'],
            ['frontdesk','Front Desk','Reservations and front desk'],
            ['cashier','Cashier','POS cashier'],
            ['stores','Stores','Stores and inventory'],
            ['accounts','Accounts','Finance and reports'],
            ['housekeeping','Housekeeping','Housekeeping team'],
            ['owner','Owner','Owner / executive access'],
            ['user','User','Basic user'],
        ];

        $stmt = $pdo->prepare("
            INSERT INTO roles (role_key, role_name, description, is_system, is_active)
            VALUES (:role_key, :role_name, :description, 1, 1)
            ON DUPLICATE KEY UPDATE
                role_name = VALUES(role_name),
                description = VALUES(description),
                is_active = 1
        ");

        foreach ($roles as $r) {
            $stmt->execute([
                ':role_key' => $r[0],
                ':role_name' => $r[1],
                ':description' => $r[2],
            ]);
        }
    }
}
if (!function_exists('ensure_users_role_key_column')) {
    function ensure_users_role_key_column(PDO $pdo): void {
        if (!users_table_exists($pdo, 'users')) {
            return;
        }

        if (!users_column_exists($pdo, 'users', 'active') && !users_column_exists($pdo, 'users', 'is_active') && !users_column_exists($pdo, 'users', 'status') && !users_column_exists($pdo, 'users', 'user_status')) {
            $pdo->exec("ALTER TABLE users ADD COLUMN active TINYINT(1) NOT NULL DEFAULT 1");
        }

        if (!users_column_exists($pdo, 'users', 'role_key')) {
            $after = users_column_exists($pdo, 'users', 'user_role') ? ' AFTER user_role' : '';
            $pdo->exec("ALTER TABLE users ADD COLUMN role_key VARCHAR(80) NULL{$after}");
        }

        if (users_column_exists($pdo, 'users', 'user_role')) {
            $pdo->exec("
                UPDATE users
                SET role_key = CASE user_role
                    WHEN 1 THEN 'super_admin'
                    WHEN 2 THEN 'admin'
                    WHEN 3 THEN 'manager'
                    WHEN 4 THEN 'frontdesk'
                    WHEN 5 THEN 'cashier'
                    WHEN 6 THEN 'stores'
                    WHEN 7 THEN 'accounts'
                    WHEN 8 THEN 'housekeeping'
                    WHEN 9 THEN 'owner'
                    ELSE 'user'
                END
                WHERE role_key IS NULL OR role_key = ''
            ");
        } else {
            $pdo->exec("
                UPDATE users
                SET role_key = 'user'
                WHERE role_key IS NULL OR role_key = ''
            ");
        }
    }
}
if (!function_exists('apply_default_permissions_for_role')) {
    function apply_default_permissions_for_role(PDO $pdo, string $roleKey): void {
        /*
         * Do not run CREATE TABLE statements while another transaction is active.
         * MySQL DDL can implicitly commit and then PDO::commit() throws:
         * "There is no active transaction".
         */
        if (!users_table_exists($pdo, 'roles') || !users_table_exists($pdo, 'role_permissions')) {
            ensure_role_permission_tables($pdo);
        }

        $roleKey = strtolower(trim($roleKey));
        if ($roleKey === '') $roleKey = 'user';

        $permissions = [
            'super_admin' => ['*'],
            'admin' => ['*'],
            'owner' => ['dashboard','executive_dashboard','owner_profit_dashboard','management_dashboard','reports','pos_sales_report','recipe_profit_report','stock_valuation_report','low_stock_report','month_end_inventory','supplier_ledger','audit_log'],
            'manager' => ['dashboard','reservations','availability_calendar','rooming','frontdesk','arrivals','departures','room_rack','housekeeping','night_audit','inventory_dashboard','pos_orders','pos_shifts','pos_approvals','pos_sales_report','recipe_profit_report','low_stock_report','reports','audit_log'],
            'frontdesk' => ['dashboard','reservations','availability_calendar','rooming','guests','frontdesk','arrivals','departures','room_rack','folios','payments'],
            'cashier' => ['dashboard','pos','pos_orders','pos_shifts'],
            'stores' => ['dashboard','inventory_dashboard','inventory_items','store_locations','suppliers','purchase_orders','grn','stock_movements','stock_take','stock_valuation_report','low_stock_report'],
            'accounts' => ['dashboard','payments','supplier_ledger','supplier_payments','pos_sales_report','stock_valuation_report','reports','audit_log'],
            'housekeeping' => ['dashboard','room_rack','housekeeping','arrivals','departures'],
            'user' => ['dashboard'],
        ];

        $allPermissions = [
            'dashboard','executive_dashboard','reservations','quotations','quotation_create','quotation_convert',
            'availability_calendar','rooming','guests','frontdesk','arrivals','departures','room_rack','housekeeping',
            'night_audit','folios','payments','inventory_dashboard','inventory_items','store_locations','suppliers',
            'purchase_orders','grn','stock_movements','stock_take','recipes','recipe_profit_report','stock_valuation_report',
            'low_stock_report','month_end_inventory','pos','pos_orders','pos_void','pos_shifts','pos_approvals','pos_sales_report',
            'restaurant_dashboard','restaurant_planner','restaurant_reservations','restaurant_reservation_calendar',
            'restaurant_orders','restaurant_cashier','restaurant_kitchen_display','restaurant_bar_display','restaurant_tables',
            'restaurant_menu','restaurant_printers','restaurant_reports','supplier_ledger','supplier_payments',
            'owner_profit_dashboard','management_dashboard','audit_log','reports','channel_dashboard','channel_settings',
            'channel_mapping','channel_push','channel_pull','channel_logs','settings','role_permissions','masters'
        ];

        $allowed = $permissions[$roleKey] ?? [];
        $allowAll = in_array('*', $allowed, true);

        $stmt = $pdo->prepare("
            INSERT INTO role_permissions
            (role_key, permission_key, can_view, can_create, can_edit, can_delete, can_approve)
            VALUES
            (:role_key, :permission_key, :can_view, :can_create, :can_edit, :can_delete, :can_approve)
            ON DUPLICATE KEY UPDATE
                can_view = VALUES(can_view),
                can_create = VALUES(can_create),
                can_edit = VALUES(can_edit),
                can_delete = VALUES(can_delete),
                can_approve = VALUES(can_approve)
        ");

        foreach ($allPermissions as $permissionKey) {
            $enabled = $allowAll || in_array($permissionKey, $allowed, true);

            /*
             * Custom roles are created in role_permissions.php.
             * This function only seeds blank permission rows for custom roles
             * unless defaults are explicitly defined above.
             */
            $stmt->execute([
                ':role_key' => $roleKey,
                ':permission_key' => $permissionKey,
                ':can_view' => $enabled ? 1 : 0,
                ':can_create' => ($enabled && !in_array($roleKey, ['owner','housekeeping','user'], true)) ? 1 : 0,
                ':can_edit' => ($enabled && !in_array($roleKey, ['owner','housekeeping','user'], true)) ? 1 : 0,
                ':can_delete' => in_array($roleKey, ['super_admin','admin'], true) ? 1 : 0,
                ':can_approve' => ($enabled && in_array($roleKey, ['super_admin','admin','owner','manager'], true)) ? 1 : 0,
            ]);
        }
    }
}
if (!function_exists('insert_flexible')) {
    function insert_flexible(PDO $pdo, string $table, array $data): int {
        $cols = [];
        $marks = [];
        $params = [];

        foreach ($data as $col => $value) {
            if (users_column_exists($pdo, $table, $col)) {
                $cols[] = "`$col`";
                $marks[] = ':' . $col;
                $params[':' . $col] = $value;
            }
        }

        if (!$cols) throw new RuntimeException("No matching columns for {$table} insert.");

        $stmt = $pdo->prepare("INSERT INTO `$table` (" . implode(',', $cols) . ") VALUES (" . implode(',', $marks) . ")");
        $stmt->execute($params);

        return (int)$pdo->lastInsertId();
    }
}
if (!function_exists('update_flexible')) {
    function update_flexible(PDO $pdo, string $table, array $data, string $whereSql, array $whereParams): void {
        $sets = [];
        $params = [];

        foreach ($data as $col => $value) {
            if (users_column_exists($pdo, $table, $col)) {
                $sets[] = "`$col` = :set_{$col}";
                $params[":set_{$col}"] = $value;
            }
        }

        if (!$sets) throw new RuntimeException("No matching columns for {$table} update.");

        foreach ($whereParams as $k => $v) $params[$k] = $v;

        $stmt = $pdo->prepare("UPDATE `$table` SET " . implode(', ', $sets) . " WHERE {$whereSql}");
        $stmt->execute($params);
    }
}

$errors = [];
$roleOptions = [];

try {
    ensure_role_permission_tables($pdo);
    if (!users_table_exists($pdo, 'users')) throw new RuntimeException('The users table does not exist.');
    ensure_users_role_key_column($pdo);
    $roleOptions = role_options($pdo);
} catch (Throwable $e) {
    $errors[] = $e->getMessage();
    $roleOptions = ['user' => 'User'];
}

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
    try {
        if (function_exists('verify_csrf')) verify_csrf();

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

        if ($action === 'save_user') {
            if (function_exists('require_permission')) require_permission($pdo, 'role_permissions', 'edit');

            $userId = (int)($_POST['id'] ?? 0);
            $title = trim((string)($_POST['title'] ?? ''));
            $firstname = trim((string)($_POST['firstname'] ?? ''));
            $lastname = trim((string)($_POST['lastname'] ?? ''));
            $username = trim((string)($_POST['username'] ?? ''));
            $email = strtolower(trim((string)($_POST['email'] ?? '')));
            $password = (string)($_POST['password'] ?? '');
            $roleKey = strtolower(trim((string)($_POST['role_key'] ?? 'user')));
            $userRole = legacy_user_role_from_role_key($roleKey);
            $phone = trim((string)($_POST['phone'] ?? ''));
            $active = isset($_POST['active']) ? 1 : 0;

            $defaultShiftFrom = date('Y-m-d 08:00:00');
            $defaultShiftTo = date('Y-m-d 17:00:00');

            if ($firstname === '') throw new RuntimeException('First name is required.');
            if ($lastname === '') throw new RuntimeException('Last name is required.');
            if ($username === '') throw new RuntimeException('Username is required.');
            if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) throw new RuntimeException('Valid email is required.');
            if ($userId <= 0 && $password === '') throw new RuntimeException('Password is required for a new user.');

            $validRoles = role_options($pdo);
            if (!isset($validRoles[$roleKey])) {
                throw new RuntimeException('Invalid role selected.');
            }

            $stmt = $pdo->prepare("SELECT COUNT(*) FROM users WHERE (username=:username OR email=:email) AND id<>:id");
            $stmt->execute([':username' => $username, ':email' => $email, ':id' => $userId]);
            if ((int)$stmt->fetchColumn() > 0) throw new RuntimeException('Username or email already exists.');

            $baseData = [
                'title' => $title,
                'firstname' => $firstname,
                'lastname' => $lastname,
                'username' => $username,
                'email' => $email,
                'user_role' => $userRole,
                'role_key' => $roleKey,
                'phone' => $phone,
                'active' => $active,
                'is_active' => $active,
                'status' => $active,
                'user_status' => $active,
                'department_id' => (int)($_POST['department_id'] ?? 0),
                'designation_id' => (int)($_POST['designation_id'] ?? 0),
                'gender' => trim((string)($_POST['gender'] ?? '')),
                'dob' => trim((string)($_POST['dob'] ?? '')) ?: null,
                'country_id' => (int)($_POST['country_id'] ?? 0),
                'state_id' => (int)($_POST['state_id'] ?? 0),
                'city_id' => (int)($_POST['city_id'] ?? 0),
                'address' => trim((string)($_POST['address'] ?? '')),
                'id_type' => trim((string)($_POST['id_type'] ?? '')),
                'id_no' => trim((string)($_POST['id_no'] ?? '')),
                'salary' => (float)($_POST['salary'] ?? 0),
                'join_date' => trim((string)($_POST['join_date'] ?? '')) ?: null,
                'remarks' => trim((string)($_POST['remarks'] ?? '')),
                'shift_from' => trim((string)($_POST['shift_from'] ?? '')) !== ''
                    ? date('Y-m-d H:i:s', strtotime((string)$_POST['shift_from']))
                    : $defaultShiftFrom,
                'shift_to' => trim((string)($_POST['shift_to'] ?? '')) !== ''
                    ? date('Y-m-d H:i:s', strtotime((string)$_POST['shift_to']))
                    : $defaultShiftTo,
            ];

            if ($password !== '') {
                $baseData['password'] = password_hash($password, PASSWORD_DEFAULT);
            }

            $pdo->beginTransaction();

            if ($userId > 0) {
                update_flexible($pdo, 'users', $baseData, 'id=:id', [':id' => $userId]);
                $savedUserId = $userId;
                $msg = 'User updated successfully.';
            } else {
                $baseData = array_merge([
                    'title' => '',
                    'phone' => '',
                    'department_id' => 0,
                    'designation_id' => 0,
                    'gender' => '',
                    'country_id' => 0,
                    'state_id' => 0,
                    'city_id' => 0,
                    'address' => '',
                    'id_type' => '',
                    'id_no' => '',
                    'id_upload' => '',
                    'salary' => 0,
                    'remarks' => '',
                    'shift_from' => date('Y-m-d H:i:s'),
                    'shift_to' => date('Y-m-d H:i:s'),
                    'token' => null,
                ], $baseData);

                $savedUserId = insert_flexible($pdo, 'users', $baseData);
                $msg = 'User created successfully.';
            }

            $pdo->commit();

            try {
                apply_default_permissions_for_role($pdo, $roleKey);
                users_flash('success', $msg . ' Role assigned: ' . role_label_from_role_key($pdo, $roleKey) . '.');
            } catch (Throwable $permissionError) {
                users_flash('warning', $msg . ' However, role permission rows could not be checked: ' . $permissionError->getMessage());
            }

            header('Location: users.php?edit_id=' . $savedUserId);
            exit;
        }

        if ($action === 'toggle_user') {
            if (function_exists('require_permission')) require_permission($pdo, 'role_permissions', 'edit');

            $id = (int)($_POST['id'] ?? 0);
            if ($id <= 0) throw new RuntimeException('Invalid user selected.');

            $stmt = $pdo->prepare("SELECT * FROM users WHERE id=:id LIMIT 1");
            $stmt->execute([':id' => $id]);
            $targetUser = $stmt->fetch(PDO::FETCH_ASSOC);
            if (!$targetUser) throw new RuntimeException('User not found.');

            $currentActive = users_is_active_value($targetUser);
            $newActive = $currentActive === 1 ? 0 : 1;

            update_flexible($pdo, 'users', users_status_update_data($pdo, $newActive), 'id=:id', [':id' => $id]);

            users_flash('success', $newActive === 1 ? 'User activated successfully.' : 'User deactivated successfully.');
            header('Location: users.php');
            exit;
        }

        if ($action === 'reset_password') {
            if (function_exists('require_permission')) require_permission($pdo, 'role_permissions', 'edit');

            $id = (int)($_POST['id'] ?? 0);
            $password = (string)($_POST['new_password'] ?? '');

            if ($id <= 0) throw new RuntimeException('Invalid user selected.');
            if (strlen($password) < 6) throw new RuntimeException('Password must be at least 6 characters.');

            $stmt = $pdo->prepare("UPDATE users SET password=:password WHERE id=:id");
            $stmt->execute([':password' => password_hash($password, PASSWORD_DEFAULT), ':id' => $id]);

            users_flash('success', 'Password reset successfully.');
            header('Location: users.php?edit_id=' . $id);
            exit;
        }

        if ($action === 'apply_role_permissions') {
            if (function_exists('require_permission')) require_permission($pdo, 'role_permissions', 'approve');

            $roleKey = strtolower(trim((string)($_POST['role_key'] ?? '')));
            if ($roleKey === '') throw new RuntimeException('Invalid role selected.');

            $validRoles = role_options($pdo);
            if (!isset($validRoles[$roleKey])) {
                throw new RuntimeException('Invalid role selected.');
            }

            apply_default_permissions_for_role($pdo, $roleKey);

            users_flash('success', 'Permission rows checked for ' . role_label_from_role_key($pdo, $roleKey) . '.');
            header('Location: users.php');
            exit;
        }

    } catch (Throwable $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        users_flash('danger', $e->getMessage());
        header('Location: users.php');
        exit;
    }
}

$editId = (int)($_GET['edit_id'] ?? 0);
$editUser = null;

if ($editId > 0) {
    try {
        $stmt = $pdo->prepare("SELECT * FROM users WHERE id=:id LIMIT 1");
        $stmt->execute([':id' => $editId]);
        $editUser = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
    } catch (Throwable $e) {
        $errors[] = 'Could not load user for edit: ' . $e->getMessage();
    }
}

$search = trim((string)($_GET['q'] ?? ''));
$roleFilter = strtolower(trim((string)($_GET['role'] ?? '')));
$statusFilter = trim((string)($_GET['status'] ?? ''));

$where = '1=1';
$params = [];

if ($search !== '') {
    /*
     * PDO can throw SQLSTATE[HY093] when the same named placeholder is reused
     * multiple times while native prepares are enabled. Use unique placeholders.
     */
    $where .= " AND (
        firstname LIKE :q_firstname
        OR lastname LIKE :q_lastname
        OR username LIKE :q_username
        OR email LIKE :q_email
        OR phone LIKE :q_phone
    )";
    $likeSearch = '%' . $search . '%';
    $params[':q_firstname'] = $likeSearch;
    $params[':q_lastname'] = $likeSearch;
    $params[':q_username'] = $likeSearch;
    $params[':q_email'] = $likeSearch;
    $params[':q_phone'] = $likeSearch;
}
if ($roleFilter !== '') {
    $where .= " AND role_key = :role_key";
    $params[':role_key'] = $roleFilter;
}
if ($statusFilter !== '') {
    $where .= " AND " . users_active_select_expr($pdo) . " = :active";
    $params[':active'] = (int)$statusFilter;
}

$users = [];
$summary = ['total' => 0, 'active' => 0, 'inactive' => 0, 'admins' => 0];
$permissionCounts = [];

try {
    $stmt = $pdo->prepare("SELECT * FROM users WHERE {$where} ORDER BY added DESC, id DESC LIMIT 700");
    $stmt->execute($params);
    $users = $stmt->fetchAll(PDO::FETCH_ASSOC);

    $activeExpr = users_active_select_expr($pdo);
    $stmt = $pdo->query("
        SELECT
            COUNT(*) total,
            SUM(CASE WHEN {$activeExpr}=1 THEN 1 ELSE 0 END) active_count,
            SUM(CASE WHEN {$activeExpr}=0 THEN 1 ELSE 0 END) inactive_count,
            SUM(CASE WHEN role_key IN ('super_admin','admin','owner') OR user_role IN (1,2,9) THEN 1 ELSE 0 END) admin_count
        FROM users
    ");
    $row = $stmt->fetch(PDO::FETCH_ASSOC) ?: [];

    $summary = [
        'total' => (int)($row['total'] ?? 0),
        'active' => (int)($row['active_count'] ?? 0),
        'inactive' => (int)($row['inactive_count'] ?? 0),
        'admins' => (int)($row['admin_count'] ?? 0),
    ];

    $stmt = $pdo->query("SELECT role_key, SUM(can_view) view_count FROM role_permissions GROUP BY role_key");
    foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $r) {
        $permissionCounts[(string)$r['role_key']] = (int)$r['view_count'];
    }
} catch (Throwable $e) {
    $errors[] = 'Could not load users: ' . $e->getMessage();
}

$flashes = users_get_flash();

require_once __DIR__ . '/../../includes/header.php';
?>

<div class="hero-band hero-band-compact no-print">
    <div class="row g-2 align-items-center">
        <div class="col-lg-8">
            <div class="page-eyebrow text-white-50"><i class="bi bi-people"></i> System Security</div>
            <div class="hero-title mt-1">Users</div>
            <div class="hero-subtitle mt-1">Manage users and assign roles directly from the roles table.</div>
        </div>
        <div class="col-lg-4 text-lg-end mt-2 mt-lg-0">
            <a href="role_permissions.php" class="btn btn-sm btn-light me-2"><i class="bi bi-shield-lock me-1"></i>Role Permissions</a>
            <a href="<?php echo BASE_URL; ?>/dashboard.php" class="btn btn-sm btn-outline-light"><i class="bi bi-speedometer2 me-1"></i>Dashboard</a>
        </div>
    </div>
</div>

<?php foreach ($flashes as $flash): ?>
    <div class="alert alert-<?php echo h($flash['type']); ?>"><?php echo h($flash['message']); ?></div>
<?php endforeach; ?>

<?php if ($errors): ?>
    <div class="alert alert-danger">
        <div class="fw-bold mb-2">Please fix the following:</div>
        <ul class="mb-0"><?php foreach ($errors as $err): ?><li><?php echo h($err); ?></li><?php endforeach; ?></ul>
    </div>
<?php endif; ?>

<div class="row g-4 mb-4">
    <div class="col-md-6 col-xl-3">
        <div class="metric-card">
            <div class="metric-icon bg-primary-subtle text-primary"><i class="bi bi-people"></i></div>
            <div><div class="metric-label">Users</div><div class="metric-value"><?php echo (int)$summary['total']; ?></div></div>
        </div>
    </div>
    <div class="col-md-6 col-xl-3">
        <div class="metric-card">
            <div class="metric-icon bg-success-subtle text-success"><i class="bi bi-person-check"></i></div>
            <div><div class="metric-label">Active</div><div class="metric-value"><?php echo (int)$summary['active']; ?></div></div>
        </div>
    </div>
    <div class="col-md-6 col-xl-3">
        <div class="metric-card">
            <div class="metric-icon bg-secondary-subtle text-secondary"><i class="bi bi-person-dash"></i></div>
            <div><div class="metric-label">Inactive</div><div class="metric-value"><?php echo (int)$summary['inactive']; ?></div></div>
        </div>
    </div>
    <div class="col-md-6 col-xl-3">
        <div class="metric-card">
            <div class="metric-icon bg-warning-subtle text-warning"><i class="bi bi-shield-check"></i></div>
            <div><div class="metric-label">Admin/Owner</div><div class="metric-value"><?php echo (int)$summary['admins']; ?></div></div>
        </div>
    </div>
</div>

<div class="row g-4">
    <div class="col-xl-4">
        <div class="card panel-card mb-4">
            <div class="card-header"><h5 class="mb-0"><?php echo $editUser ? 'Edit User' : 'Create User'; ?></h5></div>
            <div class="card-body">
                <form method="post">
                    <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
                    <input type="hidden" name="action" value="save_user">
                    <input type="hidden" name="id" value="<?php echo (int)($editUser['id'] ?? 0); ?>">

                    <div class="row g-2">
                        <div class="col-md-4 mb-3">
                            <label class="form-label">Title</label>
                            <input type="text" name="title" class="form-control" value="<?php echo h($editUser['title'] ?? ''); ?>">
                        </div>
                        <div class="col-md-8 mb-3">
                            <label class="form-label">First Name *</label>
                            <input type="text" name="firstname" class="form-control" required value="<?php echo h($editUser['firstname'] ?? ''); ?>">
                        </div>
                    </div>

                    <div class="mb-3">
                        <label class="form-label">Last Name *</label>
                        <input type="text" name="lastname" class="form-control" required value="<?php echo h($editUser['lastname'] ?? ''); ?>">
                    </div>

                    <div class="mb-3">
                        <label class="form-label">Username *</label>
                        <input type="text" name="username" class="form-control" required maxlength="32" value="<?php echo h($editUser['username'] ?? ''); ?>">
                    </div>

                    <div class="mb-3">
                        <label class="form-label">Email *</label>
                        <input type="email" name="email" class="form-control" required value="<?php echo h($editUser['email'] ?? ''); ?>">
                    </div>

                    <div class="mb-3">
                        <label class="form-label">Password <?php echo $editUser ? '(leave blank to keep)' : '*'; ?></label>
                        <input type="password" name="password" class="form-control" <?php echo $editUser ? '' : 'required'; ?>>
                    </div>

                    <?php
                        $currentRoleKey = strtolower(trim((string)($editUser['role_key'] ?? '')));
                        if ($currentRoleKey === '') {
                            $currentRoleKey = role_key_from_user_role((int)($editUser['user_role'] ?? 10));
                        }
                    ?>
                    <div class="mb-3">
                        <label class="form-label">Role *</label>
                        <select name="role_key" class="form-select" required>
                            <?php foreach ($roleOptions as $key => $label): ?>
                                <option value="<?php echo h($key); ?>" <?php echo $currentRoleKey === $key ? 'selected' : ''; ?>>
                                    <?php echo h($label); ?> (<?php echo h($key); ?>)
                                </option>
                            <?php endforeach; ?>
                        </select>
                        <div class="small text-muted mt-1">This list comes from the roles table. Add new roles in Role Permissions.</div>
                    </div>

                    <div class="mb-3">
                        <label class="form-label">Phone</label>
                        <input type="text" name="phone" class="form-control" value="<?php echo h($editUser['phone'] ?? ''); ?>">
                    </div>

                    <label class="setting-check mb-3">
                        <input type="checkbox" name="active" value="1" <?php echo users_is_active_value($editUser ?: ['active' => 1]) === 1 ? 'checked' : ''; ?>>
                        <span>Active User</span>
                    </label>

                    <div class="accordion mb-3" id="moreUserFields">
                        <div class="accordion-item">
                            <h2 class="accordion-header">
                                <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#moreFields">
                                    More Staff Details
                                </button>
                            </h2>
                            <div id="moreFields" class="accordion-collapse collapse">
                                <div class="accordion-body">
                                    <div class="row g-2">
                                        <div class="col-md-6 mb-3">
                                            <label class="form-label">Department ID</label>
                                            <input type="number" name="department_id" class="form-control" value="<?php echo h($editUser['department_id'] ?? 0); ?>">
                                        </div>
                                        <div class="col-md-6 mb-3">
                                            <label class="form-label">Designation ID</label>
                                            <input type="number" name="designation_id" class="form-control" value="<?php echo h($editUser['designation_id'] ?? 0); ?>">
                                        </div>
                                    </div>

                                    <div class="row g-2">
                                        <div class="col-md-6 mb-3">
                                            <label class="form-label">Gender</label>
                                            <input type="text" name="gender" class="form-control" value="<?php echo h($editUser['gender'] ?? ''); ?>">
                                        </div>
                                        <div class="col-md-6 mb-3">
                                            <label class="form-label">DOB</label>
                                            <input type="date" name="dob" class="form-control" value="<?php echo h($editUser['dob'] ?? ''); ?>">
                                        </div>
                                    </div>

                                    <div class="row g-2">
                                        <div class="col-md-4 mb-3">
                                            <label class="form-label">Country ID</label>
                                            <input type="number" name="country_id" class="form-control" value="<?php echo h($editUser['country_id'] ?? 0); ?>">
                                        </div>
                                        <div class="col-md-4 mb-3">
                                            <label class="form-label">State ID</label>
                                            <input type="number" name="state_id" class="form-control" value="<?php echo h($editUser['state_id'] ?? 0); ?>">
                                        </div>
                                        <div class="col-md-4 mb-3">
                                            <label class="form-label">City ID</label>
                                            <input type="number" name="city_id" class="form-control" value="<?php echo h($editUser['city_id'] ?? 0); ?>">
                                        </div>
                                    </div>

                                    <div class="mb-3">
                                        <label class="form-label">Address</label>
                                        <textarea name="address" class="form-control" rows="2"><?php echo h($editUser['address'] ?? ''); ?></textarea>
                                    </div>

                                    <div class="row g-2">
                                        <div class="col-md-6 mb-3">
                                            <label class="form-label">ID Type</label>
                                            <input type="text" name="id_type" class="form-control" value="<?php echo h($editUser['id_type'] ?? ''); ?>">
                                        </div>
                                        <div class="col-md-6 mb-3">
                                            <label class="form-label">ID No</label>
                                            <input type="text" name="id_no" class="form-control" value="<?php echo h($editUser['id_no'] ?? ''); ?>">
                                        </div>
                                    </div>

                                    <div class="row g-2">
                                        <div class="col-md-6 mb-3">
                                            <label class="form-label">Salary</label>
                                            <input type="number" step="0.01" name="salary" class="form-control" value="<?php echo h($editUser['salary'] ?? 0); ?>">
                                        </div>
                                        <div class="col-md-6 mb-3">
                                            <label class="form-label">Join Date</label>
                                            <input type="date" name="join_date" class="form-control" value="<?php echo h($editUser['join_date'] ?? ''); ?>">
                                        </div>
                                    </div>

                                    <div class="row g-2">
                                        <div class="col-md-6 mb-3">
                                            <label class="form-label">Shift From</label>
                                            <input type="datetime-local" name="shift_from" class="form-control" value="<?php echo !empty($editUser['shift_from']) ? h(date('Y-m-d\\TH:i', strtotime($editUser['shift_from']))) : ''; ?>">
                                        </div>
                                        <div class="col-md-6 mb-3">
                                            <label class="form-label">Shift To</label>
                                            <input type="datetime-local" name="shift_to" class="form-control" value="<?php echo !empty($editUser['shift_to']) ? h(date('Y-m-d\\TH:i', strtotime($editUser['shift_to']))) : ''; ?>">
                                        </div>
                                    </div>

                                    <div class="mb-3">
                                        <label class="form-label">Remarks</label>
                                        <textarea name="remarks" class="form-control" rows="2"><?php echo h($editUser['remarks'] ?? ''); ?></textarea>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <button class="btn btn-primary w-100">
                        <i class="bi bi-save me-2"></i><?php echo $editUser ? 'Update User' : 'Create User'; ?>
                    </button>

                    <?php if ($editUser): ?>
                        <a href="users.php" class="btn btn-outline-secondary w-100 mt-2">Cancel Edit</a>
                    <?php endif; ?>
                </form>

                <?php if ($editUser): ?>
                    <hr>
                    <form method="post" onsubmit="return confirm('Reset this user password?');">
                        <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
                        <input type="hidden" name="action" value="reset_password">
                        <input type="hidden" name="id" value="<?php echo (int)$editUser['id']; ?>">
                        <label class="form-label">Reset Password</label>
                        <div class="input-group">
                            <input type="password" name="new_password" class="form-control" placeholder="New password" required>
                            <button class="btn btn-outline-warning">Reset</button>
                        </div>
                    </form>
                <?php endif; ?>
            </div>
        </div>

        <div class="card panel-card">
            <div class="card-header"><h5 class="mb-0">Apply Role Permission Rows</h5></div>
            <div class="card-body">
                <form method="post">
                    <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
                    <input type="hidden" name="action" value="apply_role_permissions">
                    <div class="mb-3">
                        <label class="form-label">Role</label>
                        <select name="role_key" class="form-select">
                            <?php foreach ($roleOptions as $key => $label): ?>
                                <option value="<?php echo h($key); ?>"><?php echo h($label); ?> (<?php echo h($key); ?>)</option>
                            <?php endforeach; ?>
                        </select>
                    </div>
                    <button class="btn btn-outline-primary w-100">
                        <i class="bi bi-magic me-2"></i>Check / Seed Permission Rows
                    </button>
                </form>
            </div>
        </div>
    </div>

    <div class="col-xl-8">
        <div class="card panel-card mb-4">
            <div class="card-body">
                <form method="get" class="row g-3 align-items-end">
                    <div class="col-md-5">
                        <label class="form-label">Search</label>
                        <input type="text" name="q" class="form-control" value="<?php echo h($search); ?>" placeholder="Name / username / email / phone">
                    </div>
                    <div class="col-md-3">
                        <label class="form-label">Role</label>
                        <select name="role" class="form-select">
                            <option value="">All roles</option>
                            <?php foreach ($roleOptions as $key => $label): ?>
                                <option value="<?php echo h($key); ?>" <?php echo $roleFilter === $key ? 'selected' : ''; ?>>
                                    <?php echo h($label); ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                    </div>
                    <div class="col-md-2">
                        <label class="form-label">Status</label>
                        <select name="status" class="form-select">
                            <option value="">All</option>
                            <option value="1" <?php echo $statusFilter === '1' ? 'selected' : ''; ?>>Active</option>
                            <option value="0" <?php echo $statusFilter === '0' ? 'selected' : ''; ?>>Inactive</option>
                        </select>
                    </div>
                    <div class="col-md-2 d-grid">
                        <button class="btn btn-primary"><i class="bi bi-funnel me-2"></i>Filter</button>
                    </div>
                </form>
            </div>
        </div>

        <div class="card panel-card">
            <div class="card-header d-flex justify-content-between align-items-center">
                <h5 class="mb-0">User List</h5>
                <span class="text-muted small">Showing latest 700 users</span>
            </div>
            <div class="card-body p-0">
                <div class="table-responsive">
                    <table class="table table-modern align-middle mb-0">
                        <thead>
                        <tr>
                            <th>User</th>
                            <th>Contact</th>
                            <th>Role</th>
                            <th class="text-end">Permissions</th>
                            <th>Status</th>
                            <th>Added</th>
                            <th class="text-end">Actions</th>
                        </tr>
                        </thead>
                        <tbody>
                        <?php if (!$users): ?>
                            <tr><td colspan="7" class="text-center text-muted py-4">No users found.</td></tr>
                        <?php else: foreach ($users as $user): ?>
                            <?php
                                $roleId = (int)($user['user_role'] ?? 10);
                                $roleKey = strtolower(trim((string)($user['role_key'] ?? '')));
                                if ($roleKey === '') $roleKey = role_key_from_user_role($roleId);
                                $roleLabel = role_label_from_role_key($pdo, $roleKey);
                                $permCount = $permissionCounts[$roleKey] ?? 0;
                            ?>
                            <tr>
                                <td>
                                    <strong><?php echo h(trim(($user['firstname'] ?? '') . ' ' . ($user['lastname'] ?? ''))); ?></strong>
                                    <div class="small text-muted">@<?php echo h($user['username']); ?></div>
                                </td>
                                <td>
                                    <?php echo h($user['email']); ?>
                                    <div class="small text-muted"><?php echo h($user['phone']); ?></div>
                                </td>
                                <td>
                                    <span class="badge text-bg-primary"><?php echo h($roleLabel); ?></span>
                                    <div class="small text-muted"><?php echo h($roleKey); ?> / legacy <?php echo (int)$roleId; ?></div>
                                </td>
                                <td class="text-end">
                                    <span class="badge <?php echo $permCount > 0 ? 'text-bg-success' : 'text-bg-danger'; ?>">
                                        <?php echo (int)$permCount; ?> view
                                    </span>
                                </td>
                                <td>
                                    <?php echo users_is_active_value($user) === 1 ? '<span class="badge text-bg-success">Active</span>' : '<span class="badge text-bg-secondary">Inactive</span>'; ?>
                                </td>
                                <td><?php echo h($user['added'] ?? ''); ?></td>
                                <td class="text-end">
                                    <div class="btn-group btn-group-sm">
                                        <a href="users.php?edit_id=<?php echo (int)$user['id']; ?>" class="btn btn-outline-primary"><i class="bi bi-pencil"></i></a>
                                        <form method="post" class="d-inline">
                                            <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
                                            <input type="hidden" name="action" value="toggle_user">
                                            <input type="hidden" name="id" value="<?php echo (int)$user['id']; ?>">
                                            <button class="btn btn-outline-secondary" title="<?php echo users_is_active_value($user) === 1 ? 'Deactivate user' : 'Activate user'; ?>" onclick="return confirm('<?php echo users_is_active_value($user) === 1 ? 'Deactivate this user?' : 'Activate this user?'; ?>');"><i class="bi <?php echo users_is_active_value($user) === 1 ? 'bi-toggle-on' : 'bi-toggle-off'; ?>"></i></button>
                                        </form>
                                        <form method="post" class="d-inline">
                                            <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
                                            <input type="hidden" name="action" value="apply_role_permissions">
                                            <input type="hidden" name="role_key" value="<?php echo h($roleKey); ?>">
                                            <button class="btn btn-outline-success" title="Check permission rows for role"><i class="bi bi-shield-check"></i></button>
                                        </form>
                                    </div>
                                </td>
                            </tr>
                        <?php endforeach; endif; ?>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>

        <div class="alert alert-info mt-4">
            
        </div>
    </div>
</div>

<style>
.hero-band-compact{padding-top:16px!important;padding-bottom:16px!important;margin-bottom:18px!important}
.hero-band-compact .page-eyebrow{font-size:11px!important;letter-spacing:.08em;text-transform:uppercase}
.hero-band-compact .hero-title{font-size:24px!important;line-height:1.1!important}
.hero-band-compact .hero-subtitle{font-size:13px!important;line-height:1.35!important;max-width:720px}
.hero-band-compact .btn{border-radius:999px;padding:.35rem .75rem;font-weight:700}
.small-value{font-size:1rem!important;letter-spacing:0!important}
.setting-check{display:flex;align-items:center;gap:8px;border:1px solid rgba(15,23,42,.10);background:#fff;border-radius:14px;padding:10px 12px;font-weight:800;font-size:13px;color:#475569;cursor:pointer}
.setting-check input{width:16px;height:16px}
</style>

<?php require_once __DIR__ . '/../../includes/footer.php'; ?>
