<?php

declare(strict_types=1);

class User
{
    public static function find(int $id): ?array
    {
        return Database::fetchOne('SELECT * FROM users WHERE id = ?', [$id]);
    }

    public static function findByEmail(string $email): ?array
    {
        return Database::fetchOne('SELECT * FROM users WHERE email = ?', [$email]);
    }

    public static function findByUsername(string $username): ?array
    {
        return Database::fetchOne('SELECT * FROM users WHERE username = ?', [$username]);
    }

     
     
    public const CHANNEL_EMAIL_SUFFIX = '@imported.local';

    public static function all(int $limit = 20, int $offset = 0, string $search = '', string $kind = 'all'): array
    {
        $where = []; $params = [];
        if ($search !== '') { $where[] = '(username LIKE ? OR email LIKE ?)'; $params[] = "%{$search}%"; $params[] = "%{$search}%"; }
        if ($kind === 'members')      { $where[] = 'email NOT LIKE ?'; $params[] = '%' . self::CHANNEL_EMAIL_SUFFIX; }
        elseif ($kind === 'channels') { $where[] = 'email LIKE ?';     $params[] = '%' . self::CHANNEL_EMAIL_SUFFIX; }
        $sql = 'SELECT * FROM users' . ($where ? ' WHERE ' . implode(' AND ', $where) : '') . ' ORDER BY id DESC LIMIT ? OFFSET ?';
        $params[] = $limit; $params[] = $offset;
        return Database::fetchAll($sql, $params);
    }

    public static function count(string $search = '', string $kind = 'all'): int
    {
        $where = []; $params = [];
        if ($search !== '') { $where[] = '(username LIKE ? OR email LIKE ?)'; $params[] = "%{$search}%"; $params[] = "%{$search}%"; }
        if ($kind === 'members')      { $where[] = 'email NOT LIKE ?'; $params[] = '%' . self::CHANNEL_EMAIL_SUFFIX; }
        elseif ($kind === 'channels') { $where[] = 'email LIKE ?';     $params[] = '%' . self::CHANNEL_EMAIL_SUFFIX; }
        return Database::count('users', $where ? implode(' AND ', $where) : '1', $params);
    }
     
    public static function channelCount(): int { return self::count('', 'channels'); }

    

    public static function findOrCreateForChannel(string $name): int
    {
        $username = trim($name);
        if (mb_strlen($username) > 50) { $username = mb_substr($username, 0, 50); }
        if ($username === '') { return 0; }
        $existing = self::findByUsername($username);
        if ($existing) { return (int) $existing['id']; }
        if (!class_exists('Slug')) { require_once APP_ROOT . '/src/Helpers/Slug.php'; }
        $slug = Slug::generate($name);
        $base = $slug !== '' ? $slug : substr(md5($name), 0, 12);
        $email = 'channel.' . $base . self::CHANNEL_EMAIL_SUFFIX;
        if (self::findByEmail($email)) {
            $email = 'channel.' . substr(md5($name . microtime(true)), 0, 16) . self::CHANNEL_EMAIL_SUFFIX;
        }
        try {
            return self::create([
                'username'   => $username,
                'email'      => $email,
                'password'   => bin2hex(random_bytes(16)),
                'role'       => 'user',
                'is_active'  => 1,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
            ]);
        } catch (\PDOException $e) {
            if ($e->getCode() === '23000') {
                $existing = self::findByUsername($username);
                if ($existing) { return (int) $existing['id']; }
            }
            throw $e;
        }
    }

    public static function create(array $data): int
    {
        $plain = $data['password'] ?? '';
        if (!is_string($plain) || mb_strlen($plain) < 8) {
            throw new InvalidArgumentException('Password must be at least 8 characters');
        }
        $data['password_hash'] = Auth::hashPassword($plain);
        unset($data['password']);
        return Database::insert('users', $data);
    }

    public static function update(int $id, array $data): void
    {
        if (!empty($data['password'])) {
            $data['password_hash'] = Auth::hashPassword($data['password']);
        }
        unset($data['password']);
        Database::update('users', $data, 'id = ?', [$id]);
    }

    public static function delete(int $id): void
    {
        Database::delete('users', 'id = ?', [$id]);
    }

    public static function updatePassword(int $id, string $password): void
    {
        $hash = Auth::hashPassword($password);
        Database::update('users', ['password_hash' => $hash], 'id = ?', [$id]);
    }
}
