<?php
class UserController extends Controller
{
    public function index(): void
    {
        Auth::requirePermission('users.view');

        $search  = trim($this->get('search', ''));
        $roleF   = (int)$this->get('role', 0);
        $statusF = $this->get('status', 'all');
        $branchF = (int)$this->get('branch', 0);

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

        if ($search) {
            $where[]  = '(u.name LIKE ? OR u.username LIKE ? OR u.email LIKE ? OR u.phone LIKE ?)';
            $params   = array_merge($params, ["%$search%","%$search%","%$search%","%$search%"]);
        }
        if ($roleF)              { $where[] = 'u.role_id = ?';   $params[] = $roleF; }
        if ($branchF)            { $where[] = 'u.branch_id = ?'; $params[] = $branchF; }
        if ($statusF !== 'all')  { $where[] = 'u.status = ?';    $params[] = $statusF; }

        // Safe: check if last_active column exists before using it
        try {
            $hasLastActive = (bool)Database::fetchColumn(
                "SELECT COUNT(*) FROM information_schema.COLUMNS
                 WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='users' AND COLUMN_NAME='last_active'"
            );
        } catch (\Exception $e) { $hasLastActive = false; }

        $lastActiveSql = $hasLastActive
            ? "TIMESTAMPDIFF(SECOND, u.last_active, NOW()) AS seconds_ago"
            : "9999 AS seconds_ago";

        $users = Database::fetchAll(
            "SELECT u.*, r.role_name,
                    COALESCE(b.name, 'Main Branch') AS branch_name,
                    {$lastActiveSql}
             FROM users u
             JOIN roles r ON r.id = u.role_id
             LEFT JOIN branches b ON b.id = u.branch_id
             WHERE " . implode(' AND ', $where) . "
             ORDER BY u.status DESC, u.name ASC",
            $params
        );

        $roles      = Database::fetchAll('SELECT id, role_name FROM roles ORDER BY role_name');
        $branches   = Database::fetchAll("SELECT id, name FROM branches WHERE status='active' ORDER BY is_main DESC, name");
        $totalUsers = (int)Database::fetchColumn('SELECT COUNT(*) FROM users');
        $activeCount= (int)Database::fetchColumn("SELECT COUNT(*) FROM users WHERE status='active'");
        $roleBreakdown = Database::fetchAll(
            'SELECT r.role_name, COUNT(*) AS cnt FROM users u
             JOIN roles r ON r.id = u.role_id
             WHERE u.status = \'active\'
             GROUP BY r.id ORDER BY cnt DESC'
        );

        $pageTitle  = 'User Management';
        $breadcrumb = [['label' => 'Users']];
        ob_start();
        require APP_PATH . '/views/users/index.php';
        $content = ob_get_clean();
        require APP_PATH . '/views/layouts/main.php';
    }
    public function create(): void
    {
        Auth::requirePermission('users.create');
        $roles    = Database::fetchAll('SELECT id,role_name FROM roles ORDER BY role_name');
        $branches = Database::fetchAll("SELECT id,name FROM branches WHERE status='active'");
        $pageTitle='Add User';
        ob_start(); require APP_PATH.'/views/users/form.php'; $content=ob_get_clean();
        require APP_PATH.'/views/layouts/main.php';
    }
    public function store(): void
    {
        Auth::requirePermission('users.create'); Auth::requireCsrf();
        $d = $this->userData();
        if (!$d['password']) { $this->flash('error','Password required.'); $this->back(); return; }
        $hash = password_hash($d['password'], PASSWORD_ALGO, PASSWORD_OPTIONS);
        try {
            Database::insert('INSERT INTO users (role_id,branch_id,name,username,email,password_hash,phone,status) VALUES (?,?,?,?,?,?,?,?)',
                [$d['role_id'],$d['branch_id'],$d['name'],$d['username'],$d['email'],$hash,$d['phone'],'active']);
            redirectWith(APP_URL.'/users','success','User created.');
        } catch (PDOException) {
            $this->flash('error','Username or email already exists.');
            $this->redirect(APP_URL.'/users/create');
        }
    }
    public function edit(string $id): void
    {
        Auth::requirePermission('users.edit');
        $user     = Database::fetchOne('SELECT * FROM users WHERE id=?',[(int)$id]);
        if (!$user) { http_response_code(404); die('Not found.'); }
        $roles    = Database::fetchAll('SELECT id,role_name FROM roles ORDER BY role_name');
        $branches = Database::fetchAll("SELECT id,name FROM branches WHERE status='active'");
        $pageTitle='Edit User';
        ob_start(); require APP_PATH.'/views/users/form.php'; $content=ob_get_clean();
        require APP_PATH.'/views/layouts/main.php';
    }
    public function update(string $id): void
    {
        Auth::requirePermission('users.edit'); Auth::requireCsrf();
        $d = $this->userData();
        $sql = 'UPDATE users SET role_id=?,branch_id=?,name=?,username=?,email=?,phone=?,status=? WHERE id=?';
        $p   = [$d['role_id'],$d['branch_id'],$d['name'],$d['username'],$d['email'],$d['phone'],$d['status'],(int)$id];
        if ($d['password']) {
            $sql = 'UPDATE users SET role_id=?,branch_id=?,name=?,username=?,email=?,phone=?,status=?,password_hash=? WHERE id=?';
            $p   = [$d['role_id'],$d['branch_id'],$d['name'],$d['username'],$d['email'],$d['phone'],$d['status'],
                    password_hash($d['password'],PASSWORD_ALGO,PASSWORD_OPTIONS),(int)$id];
        }
        Database::execute($sql,$p);
        redirectWith(APP_URL.'/users','success','User updated.');
    }
    public function toggle(string $id): void
    {
        Auth::requirePermission('users.edit'); Auth::requireCsrf();
        if ((int)$id === Auth::id()) { $this->flash('error','Cannot deactivate yourself.'); $this->back(); return; }
        Database::execute("UPDATE users SET status=IF(status='active','inactive','active') WHERE id=?",[(int)$id]);
        redirectWith(APP_URL.'/users','success','User status updated.');
    }

    public function delete(string $id): void
    {
        Auth::requirePermission('users.delete'); Auth::requireCsrf();
        $uid = (int)$id;
        if ($uid === Auth::id()) {
            redirectWith(APP_URL.'/users','error','Cannot delete yourself.');
            return;
        }
        $user = Database::fetchOne('SELECT * FROM users WHERE id=?', [$uid]);
        if (!$user) { redirectWith(APP_URL.'/users','error','User not found.'); return; }
        Database::execute('UPDATE users SET status=? WHERE id=?', ['inactive', $uid]);
        Auth::logAudit(Auth::id(), 'user_delete', 'users',
            "Deactivated user: {$user['username']}");
        redirectWith(APP_URL.'/users','success',"User \"{$user['name']}\" deactivated.");
    }

    public function changeRole(string $id): void
    {
        Auth::requirePermission('users.edit'); Auth::requireCsrf();
        $uid    = (int)$id;
        $roleId = (int)$this->post('role_id', 0);
        if ($uid === Auth::id() && Auth::role() === 'super_admin') {
            redirectWith(APP_URL.'/users','error','Cannot change your own super_admin role.');
            return;
        }
        $role = Database::fetchOne('SELECT id FROM roles WHERE id=?', [$roleId]);
        if (!$role) { redirectWith(APP_URL.'/users','error','Invalid role.'); return; }
        Database::execute('UPDATE users SET role_id=? WHERE id=?', [$roleId, $uid]);
        // Reload session permissions if user changed their own role
        if ($uid === Auth::id()) {
            $_SESSION['role_id'] = $roleId;
            $_SESSION['permissions'] = array_column(
                Database::fetchAll(
                    'SELECT p.permission_key FROM role_permissions rp
                     JOIN permissions p ON p.id = rp.permission_id
                     WHERE rp.role_id=?', [$roleId]
                ), 'permission_key'
            );
        }
        redirectWith(APP_URL.'/users','success','User role updated.');
    }

    private function userData(): array
    {
        return ['role_id'=>(int)$this->post('role_id'),'branch_id'=>$this->post('branch_id')?:(null),
            'name'=>trim($this->post('name','')),'username'=>trim($this->post('username','')),
            'email'=>trim($this->post('email','')),'phone'=>trim($this->post('phone','')),
            'password'=>$this->post('password',''),'status'=>$this->post('status','active')];
    }
}