import { api } from "../core/api.js";
import { $, esc, icon, toast } from "../core/ui.js";
import { track } from "./jobs.js";

const CURATED_MODELS = [
  {
    id: "qwen-coder-32b",
    name: "Qwen 2.5 Coder 32B",
    repo: "unsloth/Qwen2.5-Coder-32B-Instruct-GGUF",
    file: "Qwen2.5-Coder-32B-Instruct-Q4_K_M.gguf",
    desc: "Top-Tier lokales Coder-Modell. Braucht ca. 24GB VRAM.",
    params_b: 32, quant: "Q4_K_M", ctx: 32768, alias: "coder"
  },
  {
    id: "qwen-coder-7b",
    name: "Qwen 2.5 Coder 7B",
    repo: "unsloth/Qwen2.5-Coder-7B-Instruct-GGUF",
    file: "Qwen2.5-Coder-7B-Instruct-Q4_K_M.gguf",
    desc: "Schneller Coder. Perfekte Balance aus Speed und Qualität.",
    params_b: 7, quant: "Q4_K_M", ctx: 32768, alias: "coder-fast"
  },
  {
    id: "llama3-vision-11b",
    name: "Llama 3.2 Vision 11B",
    repo: "unsloth/Llama-3.2-11B-Vision-Instruct-GGUF",
    file: "Llama-3.2-11B-Vision-Instruct-Q4_K_M.gguf",
    desc: "Modell für Bilderkennung und multimodale Tasks.",
    params_b: 11, quant: "Q4_K_M", ctx: 8192, alias: "vision"
  },
  {
    id: "qwen-general-7b",
    name: "Qwen 2.5 7B",
    repo: "unsloth/Qwen2.5-7B-Instruct-GGUF",
    file: "Qwen2.5-7B-Instruct-Q4_K_M.gguf",
    desc: "Hervorragendes Generalist/Scout Modell.",
    params_b: 7, quant: "Q4_K_M", ctx: 8192, alias: "scout"
  }
];

// Lokale Mathe entfernt. Wir nutzen jetzt das Backend.

let lastSys = null;
let currentResults = [];
let currentAnalysis = null;
let activeFilter = "";

const FILTERS = [
  { id: "", label: "Alle" },
  { id: "coder", label: "Coding" },
  { id: "vision", label: "Vision / Multimodal" },
  { id: "roleplay", label: "Roleplay" },
  { id: "german", label: "Deutsch" }
];

function mount() {
  const c = $(".view[data-view='cookbook']");
  
  const filtersHtml = FILTERS.map(f => 
    `<button class="ghost filter-btn ${activeFilter === f.id ? 'active' : ''}" style="margin-right:8px; border-radius:16px; padding:6px 16px; ${activeFilter === f.id ? 'background:var(--hi); color:var(--bg)' : 'background:var(--bg); border:1px solid var(--line)'}" onclick="window.setFilter('${f.id}')">${f.label}</button>`
  ).join("");

  c.innerHTML = `
    <div class="card" style="padding-bottom:32px">
      <div style="max-width:600px; margin:0 auto; text-align:center;">
        <h2 style="margin-top:20px; margin-bottom:8px">App Store für Modelle</h2>
        <p class="meta" style="margin-bottom:24px">Entdecke Modelle live auf HuggingFace, Hardware-Fit inklusive.</p>
        
        <div style="display:flex; gap:12px; position:relative">
          <input id="cb-search" class="tokin" style="flex:1; padding:12px 18px; font-size:16px; border-radius:12px;" placeholder="Nach Modellen suchen (z.B. Llama 3)...">
          <button class="primary" id="cb-btn-search" style="border-radius:12px; padding:0 24px;">Suchen</button>
        </div>
        
        <div id="cb-filters" style="margin-top:20px; display:flex; justify-content:center; flex-wrap:wrap; gap:8px">
          ${filtersHtml}
        </div>
      </div>
    </div>

    <div class="card-h" style="margin-top:24px"><h3 id="cb-section-title">Kuratierte Empfehlungen</h3></div>
    <div class="grid grid-3" id="cb-grid"></div>

    <!-- Modal für HuggingFace Modell Details -->
    <div id="cb-modal" style="display:none; position:fixed; top:0; left:0; right:0; bottom:0; background:rgba(0,0,0,0.8); z-index:100; align-items:center; justify-content:center;">
      <div class="card" style="width:100%; max-width:600px; max-height:80vh; overflow-y:auto; position:relative">
        <button id="cb-modal-close" class="ghost" style="position:absolute; top:12px; right:12px;">Schließen</button>
        <h2 id="cb-m-title" style="margin-top:0">Modell</h2>
        <p class="meta" id="cb-m-repo">repo/name</p>
        
        <div style="margin-top:24px">
          <label>Wähle eine Quantisierung (GGUF-Datei)</label>
          <select id="cb-m-files" class="tokin" style="width:100%; margin-top:8px; padding:12px"></select>
          <div id="cb-m-loading" class="meta" style="margin-top:8px; display:none">Lade Dateien...</div>
        </div>

        <div style="margin-top:24px; display:flex; gap:12px">
           <div style="flex:1">
             <label>Alias (Rolle)</label>
             <input id="cb-m-alias" class="tokin" style="width:100%; margin-top:8px" placeholder="z.B. coder">
           </div>
           <div style="flex:1">
             <label>Context-Size</label>
             <input id="cb-m-ctx" class="tokin" style="width:100%; margin-top:8px" value="8192" type="number">
           </div>
        </div>

        <div id="cb-m-fit-container" style="margin-top:24px; padding:16px; background:var(--bg); border:1px solid var(--line); border-radius:8px; display:flex; justify-content:space-between; align-items:center;">
           <div>
             <div style="font-weight:600; font-size:14px; margin-bottom:4px;">Ressourcen-Check</div>
             <div class="meta" id="cb-m-fit-text">Berechne...</div>
           </div>
           <div id="cb-m-fit-badge"></div>
        </div>

        <button class="primary" id="cb-m-download" style="width:100%; margin-top:24px; padding:12px">Herunterladen & Einpflegen</button>
      </div>
    </div>
  `;

  $("#cb-btn-search").addEventListener("click", doSearch);
  $("#cb-search").addEventListener("keydown", e => { if (e.key === "Enter") doSearch(); });
  $("#cb-modal-close").addEventListener("click", () => $("#cb-modal").style.display = "none");
  $("#cb-m-download").addEventListener("click", doDownload);
  
  $("#cb-m-files").addEventListener("change", updateLiveFit);
  $("#cb-m-ctx").addEventListener("change", reanalyzeCtx);

  renderCurated();
}

// Aktuelle Analyse-Daten vom Backend
let currentAnalysis = null;

function updateLiveFit() {
  const file = $("#cb-m-files").value;
  if (!currentAnalysis || !file) {
    $("#cb-m-fit-container").style.display = "none";
    return;
  }
  
  const fData = currentAnalysis.files.find(f => f.filename === file);
  if (!fData) return;
  
  const fit = fData.fit;
  const cls = fit.level === "perfect" ? "b-run" : (fit.level === "marginal" ? "b-load" : "b-err");
  
  $("#cb-m-fit-container").style.display = "flex";
  $("#cb-m-fit-text").innerHTML = `Geschätzter Bedarf: <b>~${fit.req_gb.toFixed(1)} GB RAM/VRAM</b> <br><small class="meta">${currentAnalysis.params_b}B Params · ${fData.quant} · ~${Math.round(fit.tps)} t/s</small>`;
  $("#cb-m-fit-badge").innerHTML = `<span class="badge ${cls}">${fit.text}</span>`;
  
  // Wenn "too_tight", machen wir den Download-Button gelb zur Warnung, erlauben ihn aber
  const btn = $("#cb-m-download");
  if (fit.level === "too_tight") {
    btn.className = "primary warn";
    btn.innerHTML = "Trotzdem herunterladen (OOM Risiko!)";
  } else {
    btn.className = "primary";
    btn.innerHTML = "Herunterladen & Einpflegen";
  }
}

async function reanalyzeCtx() {
  if (!currentAnalysis) return;
  const ctx = parseInt($("#cb-m-ctx").value) || 8192;
  const repo = currentAnalysis.repo;
  const file = $("#cb-m-files").value;
  
  $("#cb-m-fit-text").innerHTML = "Berechne neues Context-Limit...";
  try {
    const res = await api("/api/cookbook/analyze", {
      method: "POST", body: JSON.stringify({ repo_id: repo, ctx })
    });
    currentAnalysis = res;
    // Auswahl beibehalten
    $("#cb-m-files").value = file;
    updateLiveFit();
  } catch(e) {}
}

window.setFilter = (filterId) => {
  activeFilter = filterId;
  const buttons = document.querySelectorAll('.filter-btn');
  buttons.forEach(b => {
    b.style.background = 'var(--bg)';
    b.style.color = '';
    b.style.border = '1px solid var(--line)';
  });
  
  const idx = FILTERS.findIndex(f => f.id === filterId);
  if (idx !== -1 && buttons[idx]) {
    buttons[idx].style.background = 'var(--hi)';
    buttons[idx].style.color = 'var(--bg)';
    buttons[idx].style.border = 'none';
  }
  
  doSearch();
};

async function doSearch() {
  let q = $("#cb-search").value.trim();
  
  if (activeFilter) {
     q = q ? (q + " " + activeFilter) : activeFilter;
  }
  
  if (!q) return renderCurated();

  const btn = $("#cb-btn-search");
  btn.disabled = true; btn.textContent = "Lade...";
  $("#cb-section-title").textContent = "Suchergebnisse für: " + esc(q);
  $("#cb-grid").innerHTML = `<div class="meta" style="grid-column:1/-1; text-align:center; padding:40px">Suche auf HuggingFace...</div>`;

  try {
    const url = `https://huggingface.co/api/models?search=${encodeURIComponent(q)}&filter=gguf&sort=downloads&direction=-1&limit=12`;
    const r = await fetch(url);
    const data = await r.json();
    currentResults = data;
    renderResults(data);
  } catch (e) {
    $("#cb-grid").innerHTML = `<div class="alert err" style="grid-column:1/-1">${esc(e.message)}</div>`;
  }
  btn.disabled = false; btn.textContent = "Suchen";
}

function renderResults(results) {
  const grid = $("#cb-grid");
  if (!results || results.length === 0) {
    grid.innerHTML = `<div class="meta" style="grid-column:1/-1; text-align:center; padding:40px">Keine GGUF-Modelle gefunden.</div>`;
    return;
  }

  grid.innerHTML = results.map((m, i) => `
    <div class="card" style="display:flex; flex-direction:column; cursor:pointer" onclick="window.openModelModal(${i})">
      <h3 style="margin:0; font-size:16px; word-break:break-all">${esc(m.id.split('/').pop())}</h3>
      <div class="meta" style="font-size:12px; margin-top:4px">${esc(m.author)}</div>
      <div style="flex:1; margin-top:16px;"></div>
      <div style="display:flex; justify-content:space-between; align-items:center; margin-top:16px">
        <span class="badge b-idle" style="font-size:11px">GGUF</span>
        <span class="meta" style="font-size:12px">⬇ ${(m.downloads||0).toLocaleString()}</span>
      </div>
    </div>
  `).join("");
}

// Global hook for inline onclick
window.openModelModal = async (index) => {
  const m = currentResults[index];
  if (!m) return;
  $("#cb-modal").style.display = "flex";
  $("#cb-m-title").textContent = m.id.split('/').pop();
  $("#cb-m-repo").textContent = m.id;
  $("#cb-m-files").innerHTML = "";
  $("#cb-m-alias").value = m.id.split('/').pop().toLowerCase().replace(/[^a-z0-9]/g, "-");
  
  $("#cb-m-files").style.display = "none";
  $("#cb-m-loading").style.display = "block";
  $("#cb-m-download").disabled = true;

  try {
    const ctx = parseInt($("#cb-m-ctx").value) || 8192;
    const res = await api("/api/cookbook/analyze", {
      method: "POST", body: JSON.stringify({ repo_id: m.id, ctx })
    });
    
    currentAnalysis = res;
    
    $("#cb-m-loading").style.display = "none";
    $("#cb-m-files").style.display = "block";
    
    if (!res.files || res.files.length === 0) {
      $("#cb-m-files").innerHTML = "<option value=''>Keine GGUF-Dateien gefunden.</option>";
      $("#cb-m-fit-container").style.display = "none";
    } else {
      // Optische Indikatoren im Dropdown
      $("#cb-m-files").innerHTML = res.files.map(f => {
        let mark = "";
        if (f.fit.level === "perfect") mark = "🟢";
        else if (f.fit.level === "marginal") mark = "🟡";
        else mark = "🔴";
        return `<option value="${esc(f.filename)}">${mark} ${esc(f.filename)}</option>`;
      }).join("");
      
      $("#cb-m-download").disabled = false;
      updateLiveFit();
    }
  } catch(e) {
    $("#cb-m-loading").textContent = "Fehler: " + e.message;
  }
};

async function doDownload() {
  const repo = $("#cb-m-repo").textContent;
  const file = $("#cb-m-files").value;
  const alias = $("#cb-m-alias").value.trim();
  const ctx = parseInt($("#cb-m-ctx").value) || 8192;
  
  if (!repo || !file || !alias) return toast("Bitte alle Felder ausfüllen.", true);

  $("#cb-m-download").disabled = true;
  $("#cb-m-download").textContent = "Starte...";

  try {
    const res = await api("/api/download", {
      method: "POST",
      body: JSON.stringify({ repo, file })
    });
    
    // Register directly, jobengine will download it, MC will pick it up when done
    await api("/api/register", {
      method: "POST",
      body: JSON.stringify({ alias, model_path: res.expected_path, ctx })
    });

    toast("Download gestartet! Siehe Aktivitäten.");
    $("#cb-modal").style.display = "none";
    track(res.job_id); // open in jobs
    // Switch to activity tab
    document.querySelector(".nav-item[data-view='activity']").click();
    
  } catch (e) {
    toast("Fehler: " + e.message, true);
  }
  
  $("#cb-m-download").disabled = false;
  $("#cb-m-download").textContent = "Herunterladen & Einpflegen";
}

async function renderCurated() {
  $("#cb-section-title").textContent = "Kuratierte Empfehlungen";
  const grid = $("#cb-grid");
  if (!grid) return;
  
  grid.innerHTML = "<div class='meta' style='grid-column:1/-1;text-align:center;padding:40px'>Berechne Hardware-Fit für Empfehlungen...</div>";
  
  try {
    let html = "";
    for (let i = 0; i < CURATED_MODELS.length; i++) {
      const m = CURATED_MODELS[i];
      const fit = await api("/api/cookbook/evaluate", {
        method: "POST", body: JSON.stringify({ params_b: m.params_b, quant: m.quant, ctx: m.ctx })
      });
      
      const cls = fit.level === "perfect" ? "b-run" : (fit.level === "marginal" ? "b-load" : "b-err");
      
      html += `
        <div class="card" style="display:flex; flex-direction:column; cursor:pointer" onclick="window.openCuratedModal(${i})">
          <div style="display:flex; justify-content:space-between; align-items:center;">
            <h3 style="margin:0; font-size:16px">${esc(m.name)}</h3>
            <span class="badge ${cls}">${fit.text}</span>
          </div>
          <div style="font-size:13px; color:var(--mut); margin-top:12px; flex:1; line-height:1.5;">
            ${m.desc}
          </div>
          <div style="display:flex; justify-content:space-between; margin-top:16px; font-size:12px" class="meta">
            <span>~${fit.req_gb.toFixed(1)} GB RAM/VRAM · ~${Math.round(fit.tps)} t/s</span>
            <span>${m.quant}</span>
          </div>
        </div>
      `;
    }
    grid.innerHTML = html;
  } catch (e) {
    grid.innerHTML = `<div class="alert err" style="grid-column:1/-1">Fehler beim Laden der Empfehlungen: ${e.message}</div>`;
  }
}

window.openCuratedModal = async (index) => {
  const m = CURATED_MODELS[index];
  if (!m) return;
  $("#cb-modal").style.display = "flex";
  $("#cb-m-title").textContent = m.name;
  $("#cb-m-repo").textContent = m.repo;
  $("#cb-m-files").innerHTML = `<option value="${esc(m.file)}">${esc(m.file)}</option>`;
  $("#cb-m-files").style.display = "block";
  $("#cb-m-loading").style.display = "none";
  $("#cb-m-alias").value = m.alias;
  $("#cb-m-ctx").value = m.ctx;
  $("#cb-m-download").disabled = false;
  
  // Wir nutzen die neue API Struktur auch für das simulierte Modal
  try {
      const fit = await api("/api/cookbook/evaluate", {
        method: "POST", body: JSON.stringify({ params_b: m.params_b, quant: m.quant, ctx: m.ctx })
      });
      currentAnalysis = {
          repo: m.repo,
          params_b: m.params_b,
          files: [{ filename: m.file, quant: m.quant, fit: fit }]
      };
      updateLiveFit();
  } catch(e) {}
};

function onSystem(sys) {
  lastSys = sys;
  if (!$("#cb-search").value.trim()) renderCurated();
}

function unmount() {}

export default { id: "cookbook", mount, unmount, onSystem };
