<?php
class Professional
{
    public static function allActive(): array
    {
        Database::migrate();
        $stmt = Database::pdo()->query('SELECT * FROM professionals WHERE is_active = 1 ORDER BY name');
        return $stmt->fetchAll();
    }

    public static function all(): array
    {
        Database::migrate();
        $stmt = Database::pdo()->query('SELECT * FROM professionals ORDER BY is_active DESC, name');
        return $stmt->fetchAll();
    }

    public static function find(int $id): ?array
    {
        Database::migrate();
        $stmt = Database::pdo()->prepare('SELECT * FROM professionals WHERE id = ? LIMIT 1');
        $stmt->execute([$id]);
        $professional = $stmt->fetch();
        return $professional ?: null;
    }

    public static function create(string $name, string $type, string $whatsapp = '', string $username = '', string $password = '', string $adminNotes = '', int $canManageTheoryGroups = 0, int $canManageTheoryVideos = 0, int $dailyLessonLimit = 0): array
    {
        Database::migrate();
        $username = self::normalizeUsername($username);
        if ($username !== '' && self::usernameExists($username)) {
            return ['ok' => false, 'message' => 'Este usurio de instrutor j est em uso.'];
        }
        $passwordHash = $password !== '' ? password_hash($password, PASSWORD_DEFAULT) : null;
        $dailyLessonLimit = max(0, min(99, $dailyLessonLimit));
        $stmt = Database::pdo()->prepare('INSERT INTO professionals (name, type, whatsapp, username, password_hash, access_enabled, admin_notes, can_manage_theory_groups, can_manage_theory_videos, daily_lesson_limit, is_active, panel_token, created_at) VALUES (?, ?, ?, ?, ?, 1, ?, ?, ?, ?, 1, ?, ?)');
        $stmt->execute([trim($name), trim($type), only_digits($whatsapp), $username !== '' ? $username : null, $passwordHash, trim($adminNotes), $canManageTheoryGroups ? 1 : 0, $canManageTheoryVideos ? 1 : 0, $dailyLessonLimit, bin2hex(random_bytes(24)), date('Y-m-d H:i:s')]);
        return ['ok' => true, 'message' => 'Profissional cadastrado.'];
    }

    public static function update(int $id, string $name, string $type, string $whatsapp = '', string $username = '', string $password = '', int $accessEnabled = 1, string $adminNotes = '', int $canManageTheoryGroups = 0, int $canManageTheoryVideos = 0, int $dailyLessonLimit = 0): array
    {
        Database::migrate();
        $username = self::normalizeUsername($username);
        if ($username !== '' && self::usernameExists($username, $id)) {
            return ['ok' => false, 'message' => 'Este usurio de instrutor j est em uso.'];
        }
        if ($password !== '' && strlen($password) < 6) {
            return ['ok' => false, 'message' => 'A senha do instrutor precisa ter no mnimo 6 caracteres.'];
        }
        $dailyLessonLimit = max(0, min(99, $dailyLessonLimit));
        if ($password !== '') {
            $stmt = Database::pdo()->prepare('UPDATE professionals SET name = ?, type = ?, whatsapp = ?, username = ?, password_hash = ?, access_enabled = ?, admin_notes = ?, can_manage_theory_groups = ?, can_manage_theory_videos = ?, daily_lesson_limit = ? WHERE id = ?');
            $stmt->execute([trim($name), trim($type), only_digits($whatsapp), $username !== '' ? $username : null, password_hash($password, PASSWORD_DEFAULT), $accessEnabled ? 1 : 0, trim($adminNotes), $canManageTheoryGroups ? 1 : 0, $canManageTheoryVideos ? 1 : 0, $dailyLessonLimit, $id]);
        } else {
            $stmt = Database::pdo()->prepare('UPDATE professionals SET name = ?, type = ?, whatsapp = ?, username = ?, access_enabled = ?, admin_notes = ?, can_manage_theory_groups = ?, can_manage_theory_videos = ?, daily_lesson_limit = ? WHERE id = ?');
            $stmt->execute([trim($name), trim($type), only_digits($whatsapp), $username !== '' ? $username : null, $accessEnabled ? 1 : 0, trim($adminNotes), $canManageTheoryGroups ? 1 : 0, $canManageTheoryVideos ? 1 : 0, $dailyLessonLimit, $id]);
        }
        return ['ok' => true, 'message' => 'Profissional atualizado.'];
    }


    public static function updateAdminNotes(int $id, string $notes): array
    {
        Database::migrate();
        $stmt = Database::pdo()->prepare('UPDATE professionals SET admin_notes = ? WHERE id = ?');
        $stmt->execute([trim($notes), $id]);
        if ($stmt->rowCount() <= 0) {
            return ['ok' => false, 'message' => 'Instrutor no encontrado para salvar o bloco de notas.'];
        }
        return ['ok' => true, 'message' => 'Bloco de notas do instrutor salvo.'];
    }

    public static function delete(int $id): array
    {
        Database::migrate();
        $pdo = Database::pdo();
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM appointments WHERE professional_id = ? AND status IN ('booked','completed')");
        $stmt->execute([$id]);
        if ((int)$stmt->fetchColumn() > 0) {
            return ['ok' => false, 'message' => 'No e possivel apagar: este profissional possui aula agendada ou histrico de aula concluda. Desative o acesso em vez de apagar para preservar o histrico e os contadores.'];
        }

        $stmt = $pdo->prepare('DELETE FROM professionals WHERE id = ?');
        $stmt->execute([$id]);
        return ['ok' => $stmt->rowCount() > 0, 'message' => $stmt->rowCount() > 0 ? 'Profissional apagado com sucesso.' : 'Profissional no encontrado.'];
    }

    public static function toggle(int $id): void
    {
        Database::migrate();
        $stmt = Database::pdo()->prepare('UPDATE professionals SET is_active = CASE WHEN is_active = 1 THEN 0 ELSE 1 END WHERE id = ?');
        $stmt->execute([$id]);
    }

    public static function refreshToken(int $id): void
    {
        Database::migrate();
        $stmt = Database::pdo()->prepare('UPDATE professionals SET panel_token = ? WHERE id = ?');
        $stmt->execute([bin2hex(random_bytes(24)), $id]);
    }

    public static function findByToken(string $token): ?array
    {
        Database::migrate();
        $stmt = Database::pdo()->prepare("SELECT * FROM professionals WHERE panel_token = ? AND is_active = 1 LIMIT 1");
        $stmt->execute([$token]);
        $professional = $stmt->fetch();
        return $professional ?: null;
    }

    public static function findByUsername(string $username): ?array
    {
        Database::migrate();
        $stmt = Database::pdo()->prepare("SELECT * FROM professionals WHERE username = ? AND is_active = 1 AND access_enabled = 1 LIMIT 1");
        $stmt->execute([self::normalizeUsername($username)]);
        $professional = $stmt->fetch();
        return $professional ?: null;
    }

    public static function login(string $username, string $password): bool
    {
        $professional = self::findByUsername($username);
        if (!$professional || empty($professional['password_hash']) || !password_verify($password, $professional['password_hash'])) {
            return false;
        }
        session_regenerate_id(true);
        $_SESSION['professional_id'] = (int)$professional['id'];
        $_SESSION['professional_name'] = $professional['name'];
        unset($_SESSION['user_id'], $_SESSION['role'], $_SESSION['beginner_instructor_id']);
        return true;
    }

    public static function current(): ?array
    {
        if (empty($_SESSION['professional_id'])) {
            return null;
        }
        $professional = self::find((int)$_SESSION['professional_id']);
        if (!$professional || (int)($professional['is_active'] ?? 0) !== 1 || (int)($professional['access_enabled'] ?? 1) !== 1) {
            unset($_SESSION['professional_id'], $_SESSION['professional_name']);
            return null;
        }
        return $professional;
    }

    public static function logout(): void
    {
        unset($_SESSION['professional_id'], $_SESSION['professional_name']);
    }


    public static function canManageTheoryGroups(array|int $professional): bool
    {
        if (is_int($professional)) $professional = self::find($professional) ?: [];
        return !empty($professional['can_manage_theory_groups']);
    }

    public static function canManageTheoryVideos(array|int $professional): bool
    {
        if (is_int($professional)) $professional = self::find($professional) ?: [];
        return !empty($professional['can_manage_theory_videos']);
    }

    public static function updateProfilePhoto(int $professionalId, array $file): array
    {
        Database::migrate();
        $stmt = Database::pdo()->prepare('SELECT profile_photo_path FROM professionals WHERE id=? AND is_active=1 LIMIT 1');
        $stmt->execute([$professionalId]);
        $current = $stmt->fetch();
        if (!$current) {
            return ['ok' => false, 'message' => 'Instrutor nao encontrado ou desativado.'];
        }
        $saved = PortalMedia::saveImage($file, 'professional_profile_photos', 8388608);
        if (!$saved['ok']) {
            return $saved;
        }
        $update = Database::pdo()->prepare('UPDATE professionals SET profile_photo_path=? WHERE id=?');
        $update->execute([$saved['path'], $professionalId]);
        PortalMedia::delete($current['profile_photo_path'] ?? '');
        return ['ok' => true, 'message' => 'Foto de perfil do instrutor atualizada.'];
    }

    public static function weeklyAppointments(int $professionalId, string $weekStart): array
    {
        Database::migrate();
        $start = DateTime::createFromFormat('Y-m-d H:i:s', $weekStart . ' 00:00:00') ?: new DateTime('monday this week 00:00:00');
        $end = clone $start;
        $end->modify('+7 days');
        $stmt = Database::pdo()->prepare("SELECT a.*, u.name AS student_name, u.cpf AS student_cpf, u.whatsapp AS student_whatsapp, u.email AS student_email, u.category AS student_category, u.license_process, u.license_category, u.student_level, u.student_level_note, u.student_level_updated_at, u.profile_photo_path, u.internal_code AS student_internal_code,
                s.start_at, s.end_at
            FROM appointments a
            LEFT JOIN users u ON u.id = a.student_id
            INNER JOIN availability_slots s ON s.id = a.slot_id
            WHERE a.professional_id = ? AND a.status IN ('booked','completed') AND s.start_at >= ? AND s.start_at < ?
            ORDER BY CASE WHEN a.status='completed' OR a.lesson_confirmed_at IS NOT NULL THEN 1 ELSE 0 END ASC, s.start_at ASC");
        $stmt->execute([$professionalId, $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')]);
        return $stmt->fetchAll();
    }

    private static function normalizeUsername(string $username): string
    {
        return strtolower(trim($username));
    }

    private static function usernameExists(string $username, int $ignoreId = 0): bool
    {
        if ($username === '') {
            return false;
        }
        if ($ignoreId > 0) {
            $stmt = Database::pdo()->prepare('SELECT COUNT(*) FROM professionals WHERE username = ? AND id <> ?');
            $stmt->execute([$username, $ignoreId]);
        } else {
            $stmt = Database::pdo()->prepare('SELECT COUNT(*) FROM professionals WHERE username = ?');
            $stmt->execute([$username]);
        }
        return (int)$stmt->fetchColumn() > 0;
    }
}
