<?php

declare(strict_types=1);

namespace App\Models;

use Core\Database;

final class UserModel
{
    private Database $db;

    public function __construct()
    {
        $this->db = Database::getInstance();
    }

    public function all(int $page = 1, int $perPage = ITEMS_PER_PAGE): array
    {
        $offset = ($page - 1) * $perPage;
        return $this->db->fetchAll(
            "SELECT u.*, r.label AS role_label
               FROM users u
               JOIN roles r ON r.id = u.role_id
              WHERE r.name != 'customer'
              ORDER BY u.created_at DESC
              LIMIT ? OFFSET ?",
            [$perPage, $offset]
        );
    }

    public function count(): int
    {
        return (int) $this->db->fetchValue(
            "SELECT COUNT(*) FROM users u JOIN roles r ON r.id = u.role_id WHERE r.name != 'customer'"
        );
    }

    public function find(int $id): ?array
    {
        return $this->db->fetchOne(
            "SELECT u.*, r.name AS role_name
               FROM users u JOIN roles r ON r.id = u.role_id
              WHERE u.id = ?",
            [$id]
        );
    }

    public function emailExists(string $email, int $excludeId = 0): bool
    {
        return (int) $this->db->fetchValue(
            "SELECT COUNT(*) FROM users WHERE email = ? AND id != ?",
            [$email, $excludeId]
        ) > 0;
    }

    public function create(array $data): int
    {
        return $this->db->insert('users', $data);
    }

    public function update(int $id, array $data): int
    {
        return $this->db->update('users', $data, ['id' => $id]);
    }

    public function delete(int $id): int
    {
        return $this->db->delete('users', ['id' => $id]);
    }

    public function toggle(int $id): bool
    {
        $current = (int) $this->db->fetchValue(
            "SELECT is_active FROM users WHERE id = ?", [$id]
        );
        $this->db->update('users', ['is_active' => $current ? 0 : 1], ['id' => $id]);
        return !$current;
    }

    /** Non-customer roles for dropdown */
    public function staffRoles(): array
    {
        return $this->db->fetchAll(
            "SELECT id, name, label FROM roles WHERE name != 'customer' ORDER BY id ASC"
        );
    }

    public function allPermissions(): array
    {
        return $this->db->fetchAll("SELECT * FROM permissions ORDER BY module ASC, name ASC");
    }

    public function rolePermissions(int $roleId): array
    {
        return $this->db->fetchAll(
            "SELECT permission_id FROM role_permissions WHERE role_id = ?", [$roleId]
        );
    }

    public function syncRolePermissions(int $roleId, array $permissionIds): void
    {
        $this->db->delete('role_permissions', ['role_id' => $roleId]);
        foreach ($permissionIds as $pid) {
            $this->db->insert('role_permissions', ['role_id' => $roleId, 'permission_id' => (int)$pid]);
        }
    }

    public function resetLoginAttempts(int $id): void
    {
        $this->db->update('users', ['login_attempts' => 0, 'locked_until' => null], ['id' => $id]);
    }
}
