{% extends "base.html" %}

{% block title %}Compose — Ontoref{% endblock title %}

{% block content %}
<div class="mb-5 flex items-center justify-between">
  <div>
    <h1 class="text-xl font-bold">Agent Task Composer</h1>
    <p class="text-sm text-base-content/50 mt-0.5">Select a form template, fill fields, send to an AI provider or export.</p>
  </div>
</div>

<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">

  <!-- Left: template selector + form fields -->
  <div class="space-y-4">

    <!-- Template selector -->
    <div class="card bg-base-200 border border-base-content/10">
      <div class="card-body py-4 px-5">
        <h2 class="text-sm font-semibold mb-2">Template</h2>
        {% if forms %}
        <select id="form-select" class="select select-bordered select-sm w-full">
          <option value="">— choose a form template —</option>
          {% for f in forms %}
          <option value="{{ f.id }}">{{ f.label }}</option>
          {% endfor %}
        </select>
        {% else %}
        <p class="text-xs text-base-content/40">No forms found in <code>reflection/forms/</code>.</p>
        {% endif %}
      </div>
    </div>

    <!-- Dynamic form fields -->
    <div id="form-fields" class="card bg-base-200 border border-base-content/10 hidden">
      <div class="card-body py-4 px-5">
        <h2 class="text-sm font-semibold mb-1" id="form-name">Fields</h2>
        <p class="text-xs text-base-content/40 mb-3" id="form-description"></p>
        <div id="fields-container" class="space-y-3"></div>
      </div>
    </div>

    <!-- System prompt override -->
    <div class="card bg-base-200 border border-base-content/10">
      <div class="card-body py-4 px-5">
        <h2 class="text-sm font-semibold mb-2">System prompt <span class="text-xs font-normal text-base-content/40">(optional)</span></h2>
        <textarea id="system-prompt" rows="3"
                  placeholder="Override default system instructions for the agent..."
                  class="textarea textarea-bordered textarea-sm w-full font-mono text-xs"></textarea>
      </div>
    </div>
  </div>

  <!-- Right: prompt preview + send -->
  <div class="space-y-4">

    <!-- Assembled prompt preview -->
    <div class="card bg-base-200 border border-base-content/10">
      <div class="card-body py-4 px-5">
        <div class="flex items-center justify-between mb-2">
          <h2 class="text-sm font-semibold">Assembled prompt</h2>
          <button id="copy-btn" class="btn btn-xs btn-ghost gap-1" onclick="copyPrompt()">
            <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                    d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
            </svg>
            Copy
          </button>
        </div>
        <textarea id="prompt-preview" rows="12" readonly
                  placeholder="Fill form fields to see assembled prompt..."
                  class="textarea textarea-bordered textarea-sm w-full font-mono text-xs bg-base-300 resize-none"></textarea>
      </div>
    </div>

    <!-- Provider + actions -->
    <div class="card bg-base-200 border border-base-content/10">
      <div class="card-body py-4 px-5 space-y-3">
        <h2 class="text-sm font-semibold">Send / Export</h2>

        <div class="form-control">
          <label class="label py-1"><span class="label-text text-xs">Provider</span></label>
          <select id="provider-select" class="select select-bordered select-sm">
            {% for p in providers %}
            <option value="{{ p.id }}">{{ p.label }}</option>
            {% endfor %}
          </select>
        </div>

        <div class="flex gap-2 flex-wrap">
          <button onclick="sendToAPI()" class="btn btn-sm btn-primary gap-1.5 flex-1">
            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                    d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"/>
            </svg>
            Send to API
          </button>
          <button onclick="downloadPlan()" class="btn btn-sm btn-outline gap-1.5">
            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                    d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"/>
            </svg>
            Save as plan
          </button>
        </div>

        <!-- API response -->
        <div id="api-response" class="hidden">
          <div class="flex items-center justify-between mb-1">
            <span class="text-xs font-semibold text-base-content/60">Response</span>
            <button onclick="copyResponse()" class="btn btn-xs btn-ghost">Copy</button>
          </div>
          <div id="response-text"
               class="bg-base-300 rounded p-3 text-xs font-mono whitespace-pre-wrap max-h-64 overflow-auto"></div>
        </div>

        <div id="api-error" class="hidden alert alert-error text-xs py-2 px-3"></div>
        <div id="api-loading" class="hidden flex items-center gap-2 text-xs text-base-content/40">
          <span class="loading loading-spinner loading-xs"></span> Sending...
        </div>
      </div>
    </div>
  </div>
</div>
{% endblock content %}

{% block scripts %}
<script>
const BASE_URL = "{{ base_url }}";
let formSchema = null;

// ── Template selection ────────────────────────────────────────────────────────

document.getElementById('form-select')?.addEventListener('change', async function() {
  const id = this.value;
  if (!id) {
    document.getElementById('form-fields').classList.add('hidden');
    formSchema = null;
    updatePreview();
    return;
  }
  try {
    const resp = await fetch(`${BASE_URL}/compose/form/${encodeURIComponent(id)}`);
    if (!resp.ok) throw new Error(await resp.text());
    formSchema = await resp.json();
    renderFields(formSchema);
    updatePreview();
  } catch(e) {
    console.error('failed to load form schema', e);
  }
});

// ── Dynamic field rendering ───────────────────────────────────────────────────

function renderFields(schema) {
  document.getElementById('form-name').textContent = schema.name || '';
  document.getElementById('form-description').textContent = schema.description || '';

  const container = document.getElementById('fields-container');
  container.innerHTML = '';

  const elements = Array.isArray(schema.elements) ? schema.elements : [];
  for (const el of elements) {
    if (['section_header', 'section', 'confirm'].includes(el.type)) continue;

    const wrap = document.createElement('div');
    wrap.className = 'form-control';

    const label = document.createElement('label');
    label.className = 'label py-0.5';
    label.innerHTML = `<span class="label-text text-xs font-medium">${el.prompt || el.name}${el.required ? ' <span class="text-error">*</span>' : ''}</span>`;
    wrap.appendChild(label);

    if (el.help) {
      const help = document.createElement('p');
      help.className = 'text-xs text-base-content/40 mb-1';
      help.textContent = el.help;
      wrap.appendChild(help);
    }

    let input;
    if (el.type === 'select') {
      input = document.createElement('select');
      input.className = 'select select-bordered select-sm';
      for (const opt of (el.options || [])) {
        const o = document.createElement('option');
        o.value = opt.value;
        o.textContent = opt.label || opt.value;
        if (opt.value === el.default) o.selected = true;
        input.appendChild(o);
      }
    } else if (el.type === 'multiselect') {
      input = document.createElement('div');
      input.className = 'flex flex-wrap gap-2';
      for (const opt of (el.options || [])) {
        const lbl = document.createElement('label');
        lbl.className = 'flex items-center gap-1 text-xs cursor-pointer';
        const cb = document.createElement('input');
        cb.type = 'checkbox';
        cb.className = 'checkbox checkbox-xs';
        cb.value = opt.value;
        cb.dataset.name = el.name;
        cb.addEventListener('change', updatePreview);
        lbl.appendChild(cb);
        lbl.appendChild(document.createTextNode(opt.label || opt.value));
        input.appendChild(lbl);
      }
    } else if (el.type === 'editor') {
      input = document.createElement('textarea');
      input.className = 'textarea textarea-bordered textarea-sm w-full font-mono text-xs';
      input.rows = 4;
      input.placeholder = el.prefix_text ? el.prefix_text.replace(/^#.*\n/gm, '').trim() : '';
    } else {
      input = document.createElement('input');
      input.type = 'text';
      input.className = 'input input-bordered input-sm w-full';
      input.placeholder = el.placeholder || '';
      if (el.default) input.value = el.default;
    }

    if (input.tagName !== 'DIV') {
      input.dataset.name = el.name;
      input.addEventListener('input', updatePreview);
      input.addEventListener('change', updatePreview);
    }
    wrap.appendChild(input);
    container.appendChild(wrap);
  }

  document.getElementById('form-fields').classList.remove('hidden');
}

// ── Prompt assembly ───────────────────────────────────────────────────────────

function collectFields() {
  const fields = {};
  const container = document.getElementById('fields-container');
  container.querySelectorAll('[data-name]').forEach(el => {
    const name = el.dataset.name;
    if (el.type === 'checkbox') {
      if (!fields[name]) fields[name] = [];
      if (el.checked) fields[name].push(el.value);
    } else {
      fields[name] = el.value;
    }
  });
  return fields;
}

function updatePreview() {
  if (!formSchema) {
    document.getElementById('prompt-preview').value = '';
    return;
  }
  const fields = collectFields();
  const lines = [];
  lines.push(`# Task: ${formSchema.name || 'Agent Task'}`);
  if (formSchema.description) lines.push(`\n${formSchema.description}`);
  lines.push('\n## Parameters\n');

  const elements = Array.isArray(formSchema.elements) ? formSchema.elements : [];
  for (const el of elements) {
    if (['section_header', 'section', 'confirm'].includes(el.type)) continue;
    const val = fields[el.name];
    if (!val || (Array.isArray(val) && val.length === 0)) continue;
    const display = Array.isArray(val) ? val.join(', ') : val;
    lines.push(`**${el.prompt || el.name}**: ${display}\n`);
  }

  lines.push('\n## Instructions');
  lines.push('Execute this task according to the above parameters. Return results in structured format.');

  document.getElementById('prompt-preview').value = lines.join('\n');
}

// ── Send to API ───────────────────────────────────────────────────────────────

async function sendToAPI() {
  const prompt = document.getElementById('prompt-preview').value.trim();
  if (!prompt) { alert('Fill in form fields first.'); return; }

  const providerId = document.getElementById('provider-select').value;
  const system = document.getElementById('system-prompt').value.trim();

  document.getElementById('api-loading').classList.remove('hidden');
  document.getElementById('api-response').classList.add('hidden');
  document.getElementById('api-error').classList.add('hidden');

  try {
    const resp = await fetch(`${BASE_URL}/compose/send`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ provider_id: providerId, prompt, system }),
    });

    const data = await resp.json();

    if (!resp.ok) {
      throw new Error(data.error || JSON.stringify(data));
    }

    // Extract text from Anthropic or OpenAI response shape
    let text = '';
    if (data.content && Array.isArray(data.content)) {
      text = data.content.map(c => c.text || '').join('\n');
    } else if (data.choices && Array.isArray(data.choices)) {
      text = data.choices.map(c => c.message?.content || '').join('\n');
    } else {
      text = JSON.stringify(data, null, 2);
    }

    document.getElementById('response-text').textContent = text;
    document.getElementById('api-response').classList.remove('hidden');
  } catch(e) {
    document.getElementById('api-error').textContent = e.message || String(e);
    document.getElementById('api-error').classList.remove('hidden');
  } finally {
    document.getElementById('api-loading').classList.add('hidden');
  }
}

// ── Download as plan file ─────────────────────────────────────────────────────

function buildNclMeta(formId, fields, provider) {
  const date = new Date().toISOString().slice(0, 10);
  const fieldLines = Object.entries(fields)
    .filter(([, v]) => v !== '' && !(Array.isArray(v) && v.length === 0))
    .map(([k, v]) => {
      const val = Array.isArray(v) ? `[${v.map(s => `"${s}"`).join(', ')}]` : `"${v.replace(/"/g, '\\"')}"`;
      return `    ${k} = ${val},`;
    }).join('\n');

  return `let S = import "reflection/schemas/plan.ncl" in S.Plan & {
  template       = "${formId}",
  date           = "${date}",
  provider       = "${provider}",
  status         = 'Draft,
  linked_backlog = [],
  linked_adrs    = [],
  fields = {
${fieldLines}
  },
  dag = [],
}
`;
}

function downloadPlan() {
  const prompt = document.getElementById('prompt-preview').value.trim();
  if (!prompt) { alert('Fill in form fields first.'); return; }

  const formId   = document.getElementById('form-select').value || 'task';
  const provider = document.getElementById('provider-select').value || '';
  const date     = new Date().toISOString().slice(0, 10);
  const base     = `${date}-${formId}`;

  // Download .plan.md
  const mdBlob = new Blob([prompt], { type: 'text/markdown' });
  triggerDownload(mdBlob, `${base}.plan.md`);

  // Download .plan.ncl companion
  const fields  = collectFields();
  const nclText = buildNclMeta(formId, fields, provider);
  const nclBlob = new Blob([nclText], { type: 'text/plain' });
  // Small delay so browsers don't block the second download
  setTimeout(() => triggerDownload(nclBlob, `${base}.plan.ncl`), 100);
}

function triggerDownload(blob, filename) {
  const a = document.createElement('a');
  a.href = URL.createObjectURL(blob);
  a.download = filename;
  a.click();
  URL.revokeObjectURL(a.href);
}

// ── Copy helpers ──────────────────────────────────────────────────────────────

function copyPrompt() {
  const text = document.getElementById('prompt-preview').value;
  if (!text) return;
  navigator.clipboard.writeText(text).then(() => {
    const btn = document.getElementById('copy-btn');
    const orig = btn.innerHTML;
    btn.innerHTML = '<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg> Copied';
    setTimeout(() => { btn.innerHTML = orig; }, 1500);
  });
}

function copyResponse() {
  const text = document.getElementById('response-text').textContent;
  navigator.clipboard.writeText(text);
}

// Pre-fill from URL params (?form=...) — useful when launched from backlog "Send to agent"
(function() {
  const p = new URLSearchParams(location.search);
  const f = p.get('form');
  const sel = document.getElementById('form-select');
  if (f && sel) {
    sel.value = f;
    sel.dispatchEvent(new Event('change'));
  }
})();
</script>
{% endblock scripts %}
