<?php
class UserController {
    public function index(): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Auth::requirePermission('users.manage');

        $tid = Auth::tenantId();
        
        // Check if roles table exists for backward compatibility
        $rolesTableExists = db()->query("SHOW TABLES LIKE 'roles'")->fetch();
        
        if ($rolesTableExists) {
            $stmt = db()->prepare("SELECT u.*, r.name as role_name FROM users u LEFT JOIN roles r ON u.role_id = r.id WHERE u.tenant_id=? ORDER BY u.created_at DESC");
            $stmt->execute([$tid]);
            $users = $stmt->fetchAll();
        } else {
            $stmt = db()->prepare("SELECT * FROM users WHERE tenant_id=? ORDER BY created_at DESC");
            $stmt->execute([$tid]);
            $users = $stmt->fetchAll();
        }

        $pageTitle = 'Users & Roles';
        ob_start();
        include APP_ROOT . '/views/tenant/users/index.php';
        $content = ob_get_clean();
        include APP_ROOT . '/views/tenant/layouts/main.php';
    }

    public function create(): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Auth::requirePermission('users.manage');

        PlanGuard::enforce('users');

        // Get available roles if table exists
        $tid = Auth::tenantId();
        $rolesTableExists = db()->query("SHOW TABLES LIKE 'roles'")->fetch();
        $roles = $rolesTableExists ? Role::findByTenant($tid) : [];

        // Get both types of locations
        $shopLocations = Location::shopLocations();
        $warehouseLocations = Location::warehouseLocations();

        $pageTitle = 'Invite Team Member';
        ob_start();
        include APP_ROOT . '/views/tenant/users/create.php';
        $content = ob_get_clean();
        include APP_ROOT . '/views/tenant/layouts/main.php';
    }

    public function store(): void {
        Auth::requireLogin();
        Security::checkCsrf();
        Auth::requirePermission('users.manage');

        PlanGuard::enforce('users');

        // Check if roles table exists
        $rolesTableExists = db()->query("SHOW TABLES LIKE 'roles'")->fetch();
        
        // Get role info
        $roleId = $rolesTableExists && !empty($_POST['role_id']) ? (int)$_POST['role_id'] : null;
        $role = $roleId ? Role::findById($roleId, Auth::tenantId()) : null;
        
        // Fallback to legacy role if roles table doesn't exist
        $roleName = $role ? $role['name'] : ($_POST['role'] ?? 'teller');

        $data = [
            'tenant_id' => Auth::tenantId(),
            'name'      => Security::sanitize($_POST['name']),
            'email'     => strtolower(trim($_POST['email'])),
            'password'  => Security::hashPassword($_POST['password']),
            'role_id'   => $roleId,
            'role'      => $roleName,
            'location_id' => !empty($_POST['location_id']) ? (int)$_POST['location_id'] : null,
            'is_active' => 1
        ];

        // Check if email exists
        $stmt = db()->prepare("SELECT id FROM users WHERE email=?");
        $stmt->execute([$data['email']]);
        if ($stmt->fetch()) {
             flash('error', 'A user with this email already exists.');
             redirectBack();
        }

        // Build query dynamically based on whether role_id column exists
        if ($rolesTableExists) {
            $cols = implode(',', array_map(fn($k) => "`$k`", array_keys($data)));
            $vals = implode(',', array_fill(0, count($data), '?'));
            db()->prepare("INSERT INTO users ($cols) VALUES ($vals)")->execute(array_values($data));
        } else {
            // Legacy mode - don't include role_id
            unset($data['role_id']);
            $cols = implode(',', array_map(fn($k) => "`$k`", array_keys($data)));
            $vals = implode(',', array_fill(0, count($data), '?'));
            db()->prepare("INSERT INTO users ($cols) VALUES ($vals)")->execute(array_values($data));
        }

        // No need to refresh session on create as we are creating a new user, 
        // not updating the current one. But good practice to keep Auth logic consistent.

        flash('success', 'Team member invited successfully.');
        redirect('users');
    }

    public function edit(string $id): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Auth::requirePermission('users.manage');

        $tid = Auth::tenantId();
        $stmt = db()->prepare("SELECT * FROM users WHERE id=? AND tenant_id=?");
        $stmt->execute([$id, $tid]);
        $user = $stmt->fetch();

        if (!$user) { flash('error', 'User not found'); redirect('users'); }

        // Get available roles if table exists
        $rolesTableExists = db()->query("SHOW TABLES LIKE 'roles'")->fetch();
        $roles = $rolesTableExists ? Role::findByTenant($tid) : [];

        // Get both types of locations
        $shopLocations = Location::shopLocations();
        $warehouseLocations = Location::warehouseLocations();

        // Determine current assignment type
        $currentLocation = $user['location_id'] ? Location::findById((int)$user['location_id']) : null;
        $assignmentType = ($currentLocation && $currentLocation['type'] === 'warehouse') ? 'warehouse' : 'shop';

        $pageTitle = 'Edit User: ' . e($user['name']);
        ob_start();
        include APP_ROOT . '/views/tenant/users/edit.php';
        $content = ob_get_clean();
        include APP_ROOT . '/views/tenant/layouts/main.php';
    }

    public function update(string $id): void {
        Auth::requireLogin();
        Security::checkCsrf();
        Auth::requirePermission('users.manage');

        $tid = Auth::tenantId();
        
        // Check if roles table exists
        $rolesTableExists = db()->query("SHOW TABLES LIKE 'roles'")->fetch();
        
        // Get role info
        $roleId = $rolesTableExists && !empty($_POST['role_id']) ? (int)$_POST['role_id'] : null;
        $role = $roleId ? Role::findById($roleId, $tid) : null;
        
        // Fallback to legacy role if roles table doesn't exist
        $roleName = $role ? $role['name'] : ($_POST['role'] ?? 'teller');

        $data = [
            'name'      => Security::sanitize($_POST['name']),
            'role'      => $roleName,
            'location_id' => !empty($_POST['location_id']) ? (int)$_POST['location_id'] : null,
            'is_active' => isset($_POST['is_active']) ? 1 : 0
        ];

        if ($rolesTableExists) {
            $data['role_id'] = $roleId;
        }

        if (!empty($_POST['password'])) {
            $data['password'] = Security::hashPassword($_POST['password']);
        }

        $updates = implode(',', array_map(fn($k) => "`$k`=?", array_keys($data)));
        $stmt = db()->prepare("UPDATE users SET $updates WHERE id=? AND tenant_id=?");
        $stmt->execute([...array_values($data), (int)$id, $tid]);

        // Refresh session if updating current user
        if ((int)$id === (int)Auth::userId()) {
            Auth::refreshSession();
        }

        flash('success', 'User updated successfully.');
        redirect('users');
    }

    public function destroy(string $id): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Security::checkCsrf();
        Auth::requireRole(['admin','owner']);

        $id = (int)$id;
        
        // Prevent deleting yourself
        if ($id === (int)Auth::userId()) {
            flash('error', 'You cannot delete your own account.');
            redirect('users');
            return;
        }

        // Check if user exists
        $user = UserModel::find($id);
        if (!$user) {
            flash('error', 'User not found');
            redirect('users');
            return;
        }

        if (UserModel::delete($id)) {
            flash('success', 'User deleted successfully.');
        } else {
            flash('error', 'Unable to delete user.');
        }
        redirect('users');
    }
}
