import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Progress } from "@/components/ui/progress"; import { Badge } from "@/components/ui/badge"; import { Check, Download, Loader2, Play } from "lucide-react"; import { RECOMMENDED_MODELS, ModelRecommendation } from "@/lib/recommendation"; import { useState, useEffect } from "react"; import { invoke } from "@tauri-apps/api/core"; import { listen } from "@tauri-apps/api/event"; interface ModelSelectorProps { recommendation: ModelRecommendation; onComplete: () => void; } interface DownloadInfo { status: string; percent?: number; downloaded?: string; total?: string; speed?: string; raw: string; } export function ModelSelector({ recommendation, onComplete }: ModelSelectorProps) { const [selectedModelId, setSelectedModelId] = useState(recommendation.modelId); const [isInstalled, setIsInstalled] = useState(false); const [isDownloading, setIsDownloading] = useState(false); const [downloadProgress, setDownloadProgress] = useState(0); const [downloadStatus, setDownloadStatus] = useState(""); const [downloadInfo, setDownloadInfo] = useState(null); const selectedModel = RECOMMENDED_MODELS.find(m => m.id === selectedModelId) || RECOMMENDED_MODELS[0]; useEffect(() => { checkInstallation(selectedModelId); }, [selectedModelId]); useEffect(() => { const unlisten = listen('download-progress', (event) => { const payload = event.payload; // Tentar parsear como JSON estruturado let info: DownloadInfo | null = null; try { info = JSON.parse(payload) as DownloadInfo; } catch { // Fallback: tratar como string raw info = { status: "downloading", raw: payload, }; } if (info) { setDownloadInfo(info); // Atualizar status text const statusText = info.status === "pulling" ? "Baixando modelo..." : info.status === "verifying" ? "Verificando..." : info.status === "writing" ? "Salvando..." : info.status === "success" ? "Concluído!" : "Baixando..."; setDownloadStatus(statusText); // Atualizar progresso if (info.percent !== undefined) { setDownloadProgress(info.percent); } else { // Fallback: estimar progresso baseado no status if (info.status === "pulling") { setDownloadProgress(prev => prev < 10 ? 10 : prev); } else if (info.status === "verifying") { setDownloadProgress(90); } else if (info.status === "writing") { setDownloadProgress(95); } } // Se chegou a 100% ou success, marcar como instalado após um pequeno delay if (info.percent === 100 || info.status === "success") { setTimeout(() => { setIsInstalled(true); setIsDownloading(false); checkInstallation(selectedModelId); }, 500); } } }); return () => { unlisten.then(f => f()); }; }, [selectedModelId]); const checkInstallation = async (modelId: string) => { try { const installed = await invoke('check_if_model_installed', { name: modelId }); setIsInstalled(installed); } catch (e) { console.error("Check failed", e); } }; const handleDownload = async () => { setIsDownloading(true); setDownloadProgress(0); setDownloadStatus("Iniciando download..."); try { await invoke('pull_model', { name: selectedModelId }); // O status será atualizado pelo listener quando o download completar // Não precisamos setar aqui pois o listener já faz isso } catch (error) { console.error("Download failed", error); setDownloadStatus("Falha no download. Tente novamente."); setDownloadProgress(0); setIsDownloading(false); } }; return (
Escolha seu Modelo {selectedModelId === recommendation.modelId ? "Baseado no seu hardware, recomendamos:" : "Você selecionou um modelo personalizado:"}
{selectedModelId === recommendation.modelId && ( Recomendado )}

Sobre este modelo:

{selectedModelId === recommendation.modelId ? recommendation.reason : "Modelo alternativo selecionado. Certifique-se de ter memória suficiente."}

{isDownloading && (
{downloadStatus || "Iniciando..."} {downloadProgress}%
{downloadInfo && (downloadInfo.downloaded || downloadInfo.speed) && (
{downloadInfo.downloaded && downloadInfo.total ? `${downloadInfo.downloaded} / ${downloadInfo.total}` : downloadInfo.downloaded || ""} {downloadInfo.speed && ( {downloadInfo.speed} )}
)}
)}
{isInstalled ? ( ) : ( )}
); }