<?php
class ProfessionalMaterial
{
    public static function all(): array
    {
        Database::migrate();
        $stmt = Database::pdo()->query("SELECT m.*, p.name AS professional_name
            FROM professional_materials m
            LEFT JOIN professionals p ON p.id = m.professional_id
            ORDER BY m.created_at DESC");
        return $stmt->fetchAll();
    }

    public static function forProfessional(int $professionalId): array
    {
        Database::migrate();
        $stmt = Database::pdo()->prepare("SELECT * FROM professional_materials
            WHERE is_active = 1 AND (professional_id IS NULL OR professional_id = 0 OR professional_id = ?)
            ORDER BY created_at DESC");
        $stmt->execute([$professionalId]);
        return $stmt->fetchAll();
    }

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

    public static function findAllowed(int $id, int $professionalId): ?array
    {
        Database::migrate();
        $stmt = Database::pdo()->prepare("SELECT * FROM professional_materials
            WHERE id = ? AND is_active = 1 AND (professional_id IS NULL OR professional_id = 0 OR professional_id = ?)
            LIMIT 1");
        $stmt->execute([$id, $professionalId]);
        $material = $stmt->fetch();
        return $material ?: null;
    }

    public static function createFromUpload(array $data, array $file, array $coverFile = []): array
    {
        Database::migrate();
        $title = trim($data['title'] ?? '');
        $description = trim($data['description'] ?? '');
        $professionalId = (int)($data['professional_id'] ?? 0);
        if ($title === '') {
            return ['ok' => false, 'message' => 'Informe o título do material.'];
        }
        if (empty($file['tmp_name']) || ($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
            return ['ok' => false, 'message' => 'Envie um arquivo PDF/e-book.'];
        }
        $maxBytes = 25 * 1024 * 1024;
        if (($file['size'] ?? 0) > $maxBytes) {
            return ['ok' => false, 'message' => 'Arquivo muito grande. Limite de 25 MB.'];
        }
        $finfo = new finfo(FILEINFO_MIME_TYPE);
        $mime = $finfo->file($file['tmp_name']) ?: 'application/octet-stream';
        $allowed = [
            'application/pdf' => 'pdf',
            'application/epub+zip' => 'epub',
            'application/msword' => 'doc',
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
            'image/jpeg' => 'jpg',
            'image/png' => 'png',
            'image/webp' => 'webp',
        ];
        if (!isset($allowed[$mime])) {
            return ['ok' => false, 'message' => 'Formato não permitido. Use PDF, EPUB, DOC, DOCX ou imagem.'];
        }

        $cover = save_cover_image_upload($coverFile, 'materiais_instrutores');
        if (!$cover['ok']) {
            return ['ok' => false, 'message' => $cover['message']];
        }

        $dir = STORAGE_PATH . '/professional_materials';
        if (!is_dir($dir)) {
            mkdir($dir, 0775, true);
        }
        $filename = 'material_' . bin2hex(random_bytes(12)) . '.' . $allowed[$mime];
        $relative = 'professional_materials/' . $filename;
        $dest = $dir . '/' . $filename;
        if (!move_uploaded_file($file['tmp_name'], $dest)) {
            delete_storage_file($cover['path']);
            return ['ok' => false, 'message' => 'Não foi possível salvar o arquivo.'];
        }

        try {
            $stmt = Database::pdo()->prepare('INSERT INTO professional_materials (professional_id, title, description, file_path, original_name, mime_type, file_size, cover_path, cover_mime_type, is_active, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?)');
            $stmt->execute([
                $professionalId > 0 ? $professionalId : null,
                $title,
                $description,
                $relative,
                basename((string)($file['name'] ?? $filename)),
                $mime,
                (int)($file['size'] ?? 0),
                $cover['path'],
                $cover['mime'],
                date('Y-m-d H:i:s'),
            ]);
        } catch (Throwable $e) {
            delete_storage_file($relative);
            delete_storage_file($cover['path']);
            return ['ok' => false, 'message' => 'Não foi possível cadastrar o material.'];
        }
        return ['ok' => true, 'message' => 'Material do instrutor cadastrado com imagem.'];
    }

    public static function updateCover(int $id, array $coverFile): array
    {
        Database::migrate();
        $record = self::find($id);
        if (!$record) {
            return ['ok' => false, 'message' => 'Registro não encontrado.'];
        }
        $cover = save_cover_image_upload($coverFile, 'materiais_instrutores');
        if (!$cover['ok']) {
            return ['ok' => false, 'message' => $cover['message']];
        }
        if (empty($cover['path'])) {
            return ['ok' => false, 'message' => 'Selecione uma imagem JPG, PNG ou WEBP.'];
        }
        try {
            $stmt = Database::pdo()->prepare('UPDATE professional_materials SET cover_path = ?, cover_mime_type = ? WHERE id = ?');
            $stmt->execute([$cover['path'], $cover['mime'], $id]);
        } catch (Throwable $e) {
            delete_storage_file($cover['path']);
            return ['ok' => false, 'message' => 'Não foi possível atualizar a imagem.'];
        }
        delete_storage_file($record['cover_path'] ?? null);
        return ['ok' => true, 'message' => 'Imagem atualizada com sucesso.'];
    }

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

    public static function delete(int $id): array
    {
        Database::migrate();
        $material = self::find($id);
        if (!$material) {
            return ['ok' => false, 'message' => 'Material não encontrado.'];
        }
        $delete = Database::pdo()->prepare('DELETE FROM professional_materials WHERE id = ?');
        $delete->execute([$id]);
        delete_storage_file($material['file_path'] ?? null);
        delete_storage_file($material['cover_path'] ?? null);
        return ['ok' => true, 'message' => 'Material apagado com sucesso.'];
    }

    public static function streamFile(array $material): never
    {
        $path = STORAGE_PATH . '/' . ltrim((string)($material['file_path'] ?? ''), '/');
        if (!is_file($path)) {
            http_response_code(404);
            exit('Arquivo não encontrado.');
        }
        $mime = $material['mime_type'] ?: 'application/octet-stream';
        $downloadName = $material['original_name'] ?: (preg_replace('/[^a-z0-9_-]+/i', '_', $material['title'] ?? 'material') . '.pdf');
        header('Content-Type: ' . $mime);
        header('Content-Length: ' . filesize($path));
        header('Content-Disposition: inline; filename="' . str_replace('"', '', $downloadName) . '"');
        header('X-Content-Type-Options: nosniff');
        readfile($path);
        exit;
    }

    public static function streamCover(array $material): never
    {
        stream_storage_image($material['cover_path'] ?? null, $material['cover_mime_type'] ?? null);
    }
}
