// panes/diffusion.js — Stable Diffusion proxy.
import { registerPane } from '../app.js';
import { jget, jpost, escapeHtml } from '../lib/api.js';
import { fmtJSON, ok, err } from '../lib/ui.js';

const TPL = `
  <div class="pane-head">
    <div><div class="title">Diffusion</div><div class="sub">Generate via the diffusion sidecar.</div></div>
    <div class="grow"></div>
    <span class="pill" id="diff-pill"><span class="dot"></span><span id="diff-pill-text">—</span></span>
  </div>

  <div class="grid cols-2">
    <div class="card">
      <div class="card-title"><h2>Prompt</h2></div>
      <form id="diff-form" class="grid gap-3">
        <label class="field"><span class="lbl">Prompt</span><textarea class="input" id="diff-prompt" rows="3" required></textarea></label>
        <label class="field"><span class="lbl">Negative prompt</span><textarea class="input" id="diff-neg" rows="2"></textarea></label>
        <div class="grid cols-3 gap-3">
          <label class="field"><span class="lbl">Steps</span><input class="input" id="diff-steps" type="number" value="20" min="1"/></label>
          <label class="field"><span class="lbl">CFG</span><input class="input" id="diff-cfg" type="number" value="7" step="0.5"/></label>
          <label class="field"><span class="lbl">Sampler</span><input class="input" id="diff-sampler" placeholder="(optional)"/></label>
        </div>
        <div class="grid cols-2 gap-3">
          <label class="field"><span class="lbl">Width</span><input class="input" id="diff-w" type="number" value="512" step="64"/></label>
          <label class="field"><span class="lbl">Height</span><input class="input" id="diff-h" type="number" value="512" step="64"/></label>
        </div>
        <div class="btn-row">
          <button class="btn btn-primary" type="submit">Generate</button>
          <button class="btn btn-secondary" type="button" id="diff-models">Models</button>
          <button class="btn btn-secondary" type="button" id="diff-samplers">Samplers</button>
          <button class="btn btn-secondary" type="button" id="diff-progress">Progress</button>
        </div>
      </form>
    </div>
    <div class="card">
      <div class="card-title"><h2>Output</h2><span class="muted mono" id="diff-status">—</span></div>
      <div class="gallery" id="diff-gallery"></div>
      <h3 class="mt-3 mb-2">Meta</h3>
      <pre id="diff-meta">—</pre>
    </div>
  </div>
`;

async function probe(host) {
  try {
    const h = await jget('/api/diffusion/healthz');
    host.querySelector('#diff-pill').classList.add('ok');
    host.querySelector('#diff-pill-text').textContent = `up · ${h.backend ?? '?'}`;
  } catch (e) {
    host.querySelector('#diff-pill').classList.add('err');
    host.querySelector('#diff-pill-text').textContent = 'down';
  }
}

registerPane('diffusion', {
  label: 'Diffusion',
  init(host) {
    host.innerHTML = TPL;
    probe(host);
    host.querySelector('#diff-form').addEventListener('submit', async (e) => {
      e.preventDefault();
      host.querySelector('#diff-status').textContent = 'generating…';
      const body = {
        prompt: host.querySelector('#diff-prompt').value,
        negative_prompt: host.querySelector('#diff-neg').value,
        steps: +host.querySelector('#diff-steps').value || 20,
        width: +host.querySelector('#diff-w').value || 512,
        height: +host.querySelector('#diff-h').value || 512,
        cfg_scale: +host.querySelector('#diff-cfg').value || 7,
      };
      const s = host.querySelector('#diff-sampler').value.trim();
      if (s) body.sampler_name = s;
      try {
        const r = await jpost('/api/diffusion/v1/generate', body);
        host.querySelector('#diff-gallery').innerHTML = (r.images || []).map(b64 =>
          `<img src="data:image/png;base64,${b64}" alt="generated" />`
        ).join('');
        host.querySelector('#diff-meta').textContent = fmtJSON({ seeds: r.seeds, duration_s: r.duration_s });
        host.querySelector('#diff-status').textContent = `ok · ${r.duration_s?.toFixed?.(2) ?? '?'}s · ${(r.images||[]).length} img`;
        ok('Generated');
      } catch (e) {
        host.querySelector('#diff-status').textContent = `error ${e.status ?? ''}`;
        host.querySelector('#diff-meta').textContent = fmtJSON(e.body ?? { error: e.message });
        err(e.message);
      }
    });
    const meta = host.querySelector('#diff-meta');
    const show = async (url) => { try { meta.textContent = fmtJSON(await jget(url)); } catch (e) { meta.textContent = e.message; } };
    host.querySelector('#diff-models').addEventListener('click', () => show('/api/diffusion/v1/models'));
    host.querySelector('#diff-samplers').addEventListener('click', () => show('/api/diffusion/v1/samplers'));
    host.querySelector('#diff-progress').addEventListener('click', () => show('/api/diffusion/v1/progress'));
  },
});
