// Teklens.AI — Guided builder for Skills & Agents.
// Creating/refining a skill or agent is an AI-guided conversation, not a manual form.
// LEFT  : a reduced chat (model selector + attach + send) that drives creation & edits.
// RIGHT : live artifact tabs (Preview / Skill / Agent / Data / Template) with pencil-edit.
// Reuses globals from skills-agents.jsx & app: Icon, renderTemplatePreview, AgentMultiSelect,
// WidgetSamplePreview, WidgetCode, PreviewPane, OutputBadge, LineageBadge, saEffLineage,
// IconPicker, OutputSelector, AGENT_MODEL_DEFAULT, MODELS_LIST, SA_TOOLS.

function BuilderModelInline({ value, onChange }) {
  const [open, setOpen] = useState(false);
  const list = typeof MODELS_LIST !== "undefined" && MODELS_LIST || [];
  const cur = list.find((m) => m.label === value);
  return (
    <div className="relative inline-block">
      <button onClick={() => setOpen((o) => !o)} className="flex items-center gap-1.5 text-[13px] text-[var(--text-muted)] hover:text-[var(--text)]">
        <Icon name={cur ? cur.provider : "sparkles"} size={13} className="text-[var(--text-faint)]" />
        <span>{value}</span>
        <Icon name="chevron-down" size={12} className="text-[var(--text-faint2)]" />
      </button>
      {open &&
      <>
          <div className="fixed inset-0 z-30" onClick={() => setOpen(false)} />
          <div className="absolute left-0 top-full mt-1 w-[280px] bg-[var(--card)] rounded-lg border border-[var(--border)] shadow-xl z-40 py-1 max-h-[300px] overflow-y-auto">
            {list.map((m) =>
          <button key={m.id} onClick={() => {onChange(m.label);setOpen(false);}} className="w-full flex items-center gap-2.5 px-2.5 py-1.5 hover:bg-[var(--hover)] text-left">
                <span className="w-6 h-6 rounded bg-[var(--surface)] flex items-center justify-center text-[var(--text-2)] shrink-0"><Icon name={m.provider} size={13} /></span>
                <span className="min-w-0 flex-1"><span className="block text-[12.5px] text-[var(--text)] truncate">{m.label}</span><span className="block text-[11px] text-[var(--text-faint2)] truncate">{m.sub}</span></span>
                {m.label === value && <Icon name="check" size={13} className="text-[var(--accent)] shrink-0" />}
              </button>
          )}
          </div>
        </>
      }
    </div>);

}

// Per-skill "design the output" conversations — authored to match each skill's actual output.
const DESIGN_CHATS = {
  "risk-analyzer": [
  { role: "user", text: "For the output, make a widget: an overall risk score in a ring at the top-right with a short summary beside it, then the individual risks ranked below — each with severity, likelihood, impact and the file evidence." },
  { role: "tool", tool: "design_widget", status: "completed" },
  { role: "assistant", text: "Done. The widget leads with the **risk-score ring (top-right)** and a headline summary, then a ranked list of **risk cards** — each showing a severity dot, likelihood × impact, the `file · lines · owner` evidence and a suggested mitigation. The live preview is on the right; tweak the data structure or sample to adjust." }],

  "idea-estimator": [
  { role: "user", text: "Design the output as a widget with two gauges up top — complexity and total risk — then the top risks as a tagged list and a short resourcing breakdown below." },
  { role: "tool", tool: "design_widget", status: "completed" },
  { role: "assistant", text: "Built it. Two **dial gauges** (complexity + total risk) head the card, followed by the **top-risks list** with severity tags and a resourcing breakdown. Sample data is rendering in the preview — adjust the schema or sample to change it." }],

  "release-note-generator": [
  { role: "user", text: "The output should be an HTML page: a version + date header with a one-line theme summary, then grouped sections for New Features, Fixes and Breaking Changes." },
  { role: "tool", tool: "design_template", status: "completed" },
  { role: "assistant", text: "Here's the **HTML template** — a header band carrying `{{version}}` and `{{date}}`, the theme line, then styled category sections (Breaking Changes flagged in amber). The curly placeholders fill per run; the preview shows it with sample release data." }],

  "tech-debt-report": [
  { role: "user", text: "Make it a Markdown report — an overall debt score and the top three concerns, then a section per hotspot with severity, the evidence and a suggested fix with rough effort." },
  { role: "tool", tool: "design_template", status: "completed" },
  { role: "assistant", text: "Done — a **Markdown template** opening with the debt score and top-three concerns, then a `### Hotspot · severity` block per area with evidence and a **Fix** line. The preview renders a filled example." }]

};

function seedDesignChat(item) {
  if (DESIGN_CHATS[item.id]) return DESIGN_CHATS[item.id];
  const byOutput = {
    widget: "a **widget** — describe the layout (the key number, a summary, then the supporting detail) and I'll wire it to a data structure.",
    html: "an **HTML template** — tell me the sections and I'll lay them out with curly placeholders the skill fills each run.",
    markdown: "a **Markdown template** — tell me the headings and structure and I'll add curly placeholders for the skill to fill.",
    none: "**nothing fixed** — this skill replies inline, so there's no layout to design. Switch the output to Markdown, HTML or Widget on the Build step to design a format."
  };
  return [
  { role: "assistant", text: `Now let's design the **output**. This skill produces ${byOutput[item.output] || byOutput.none}` }];

}

// Seed the builder conversation so it reads like an AI session — separate threads per step.
function seedBuilderChat(item, kind, step) {
  if (kind === "agent") {
    return [
    { role: "user", text: `Create an agent that ${item.desc || "investigates and returns findings to the thread."}` },
    { role: "tool", tool: "scaffold_agent", status: "completed" },
    { role: "assistant", text: `I've drafted **${item.name}**. The prompt and model are on the right — refine them in chat, or click any pencil to edit directly.` }];

  }
  if (step === "design") return seedDesignChat(item);
  return [
  { role: "user", text: `Create a skill called "${item.name}" that ${item.desc || "produces a useful artefact."}` },
  { role: "tool", tool: "scaffold_skill", status: "completed" },
  { role: "assistant", text: `I've drafted **${item.name}**. The routing description, instructions and agents are on the right — refine them in chat, or click any pencil to edit a section directly.` }];

}

function BuilderChat({ item, kind, model, setModel, onRename, step }) {
  const isSkill = kind === "skill";
  const stepKey = step === "design" ? "design" : "define";
  const [msgsByStep, setMsgsByStep] = useState(() => ({
    define: seedBuilderChat(item, kind, "define"),
    design: seedBuilderChat(item, kind, "design")
  }));
  const msgs = msgsByStep[stepKey];
  const [editingName, setEditingName] = useState(false);
  const scrollRef = useRef(null);
  useEffect(() => {if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;}, [msgs]);
  const send = (text) => {
    const t = (text || "").trim();if (!t) return;
    const tool = stepKey === "design" ?
    item.output === "widget" ? "design_widget" : "design_template" :
    isSkill ? "update_skill" : "update_agent";
    const reply = stepKey === "design" ?
    `Updated the **output** — applied "${t}". The preview on the right reflects the change.` :
    `Updated **${item.name}** — applied "${t}". Check the panel on the right to review the change.`;
    setMsgsByStep((prev) => ({ ...prev, [stepKey]: [...prev[stepKey],
      { role: "user", text: t },
      { role: "tool", tool, status: "completed" },
      { role: "assistant", text: reply }] }));
  };
  const phase = isSkill ? stepKey === "design" ? "Designing the output" : "Building the skill" : "Building the agent";
  return (
    <div className="w-[46%] min-w-[380px] shrink-0 h-full flex flex-col border-r border-[var(--border)] bg-[var(--card)]">
      {/* header */}
      <div className="px-6 pt-5 pb-3 border-b border-[var(--border-soft)] shrink-0">
        <div className="flex items-center gap-2.5">
          <span className="w-7 h-7 rounded-md flex items-center justify-center bg-[var(--surface-inset)] text-[var(--text-muted)] shrink-0"><Icon name={kind === "agent" ? AGENT_ICON : SKILL_ICON} size={15} /></span>
          {editingName ?
          <input autoFocus value={item.name} onChange={(e) => onRename(e.target.value)} onBlur={() => setEditingName(false)} onKeyDown={(e) => e.key === "Enter" && setEditingName(false)}
          className="text-[19px] font-semibold text-[var(--text)] bg-transparent outline-none border-b border-[var(--accent)] min-w-0 flex-1" /> :
          <h1 className="text-[19px] font-semibold text-[var(--text)] tracking-tight truncate">{item.name}</h1>}
          <button onClick={() => setEditingName(true)} className="p-1 rounded text-[var(--text-faint2)] hover:text-[var(--text)] hover:bg-[var(--hover)] shrink-0"><Icon name="edit-line" size={14} /></button>
        </div>
        <div className="flex items-center gap-1.5 mt-1.5 text-[11.5px] text-[var(--text-faint2)] pl-[38px]">
          <Icon name={stepKey === "design" ? "eye" : "sparkles"} size={12} className="text-[var(--accent)]" /> {phase}
        </div>
      </div>
      {/* messages */}
      <div ref={scrollRef} className="flex-1 min-h-0 overflow-y-auto px-6 py-5 flex flex-col gap-4">
        {msgs.map((m, i) => <BuilderMsg key={i} m={m} />)}
      </div>
      {/* composer — same element as Ask Teklens, reduced to attach · voice · model */}
      <StandaloneComposer maxW="max-w-none" placeholder={stepKey === "design" ? "Refine the output…" : `Refine your ${kind}…`}
      model={model} setModel={setModel}
      show={{ add: false, filter: false, attach: true, mic: true, model: true }}
      onSend={send} />
    </div>);

}

function BuilderMsg({ m }) {
  if (m.role === "user")
  return <div className="self-end max-w-[88%] rounded-2xl bg-[var(--surface-inset)] px-4 py-2.5 text-[13.5px] text-[var(--text)] leading-relaxed whitespace-pre-wrap">{m.text}</div>;
  if (m.role === "tool")
  return (
    <div className="flex items-center gap-2.5 rounded-xl border border-[var(--border)] bg-[var(--card)] px-3.5 py-2.5">
        <Icon name="tool" size={14} className="text-[var(--text-faint)] shrink-0" />
        <span className="text-[12.5px] font-mono text-[var(--text-2)]">{m.tool}</span>
        <span className="inline-flex items-center gap-1 text-[11px] font-medium px-1.5 py-0.5 rounded" style={{ color: "var(--green-ink)", background: "var(--green-bg)" }}><Icon name="check" size={10} /> Completed</span>
      </div>);

  return <div className="max-w-[92%] text-[13.5px] text-[var(--text)] leading-relaxed ctx-doc">{renderTemplatePreview(m.text)}</div>;
}

// ---------- right pane: artifact tabs ----------
function BuilderTabHeader({ tabs, tab, setTab }) {
  const ICONS = { preview: "eye", skill: "file", instructions: "file", agent: "robot", agents: "robot", data: "json", template: "code", tools: "tool" };
  return (
    <div className="px-6 h-[52px] shrink-0 border-b border-[var(--border-soft)] flex items-center gap-1">
      {tabs.map((t) => {
        const on = tab === t.id;
        return (
          <button key={t.id} onClick={() => setTab(t.id)}
          className={`flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-[13px] font-medium ${on ? "bg-[var(--accent)]/[0.09] text-[var(--accent)] ring-1 ring-[var(--accent)]/30" : "text-[var(--text-muted)] hover:bg-[var(--hover)]"}`}>
            <Icon name={ICONS[t.id] || "file"} size={14} /> {t.label}
          </button>);

      })}
    </div>);

}

function PencilEdit({ editing, onToggle }) {
  return <button onClick={onToggle} className={`p-1.5 rounded-md ${editing ? "text-[var(--accent)] bg-[var(--accent)]/[0.08]" : "text-[var(--text-faint2)] hover:text-[var(--text)] hover:bg-[var(--hover)]"}`} title={editing ? "Done editing" : "Edit"}><Icon name={editing ? "check" : "edit-line"} size={15} /></button>;
}

// A rendered-markdown / inline-edit section used by most tabs.
function ProseSection({ value, onChange, placeholder }) {
  const [editing, setEditing] = useState(false);
  return (
    <div className="relative">
      <div className="absolute right-0 top-0 z-10"><PencilEdit editing={editing} onToggle={() => setEditing((e) => !e)} /></div>
      {editing ?
      <textarea autoFocus value={value || ""} onChange={(e) => onChange(e.target.value)} rows={14} placeholder={placeholder}
      className="w-full resize-none rounded-xl border border-[var(--border)] bg-[var(--surface-2)] px-4 py-3 pr-10 text-[13px] font-mono text-[var(--text)] outline-none focus:border-[var(--accent)] leading-relaxed" /> :
      <div className="ctx-doc pr-9 min-h-[80px]">{value ? renderTemplatePreview(value) : <span className="text-[var(--bar)] text-[13px]">{placeholder}</span>}</div>}
    </div>);

}

// Stepper across the top of the right pane: ① Build the skill → ② Design the output.
function BuilderStepper({ steps, step, setStep, right }) {
  const idx = steps.findIndex((s) => s.id === step);
  return (
    <div className="pl-5 pr-4 h-[56px] shrink-0 border-b border-[var(--border-soft)] flex items-center gap-2">
      {steps.map((s, i) => {
        const on = s.id === step,done = i < idx;
        return (
          <React.Fragment key={s.id}>
            {i > 0 && <div className={`h-px w-6 ${i <= idx ? "bg-[var(--accent)]/40" : "bg-[var(--border)]"}`} />}
            <button onClick={() => setStep(s.id)} className={`flex items-center gap-2 pl-1.5 pr-3 py-1.5 rounded-full ${on ? "bg-[var(--accent)]/[0.09] ring-1 ring-[var(--accent)]/30" : "hover:bg-[var(--hover)]"}`}>
              <span className={`w-6 h-6 rounded-full flex items-center justify-center text-[12px] font-semibold shrink-0 ${on ? "bg-[var(--accent)] text-white" : done ? "bg-[var(--accent)]/[0.15] text-[var(--accent)]" : "bg-[var(--surface-inset)] text-[var(--text-faint2)]"}`}>{done ? <Icon name="check" size={13} /> : i + 1}</span>
              <span className={`text-[13px] font-medium whitespace-nowrap ${on ? "text-[var(--accent)]" : "text-[var(--text-muted)]"}`}>
                <span className="hidden xl:inline">{s.label}</span>
                <span className="xl:hidden">{s.short || s.label}</span>
              </span>
            </button>
          </React.Fragment>);

      })}
      {right && <div className="ml-auto flex items-center gap-2">{right}</div>}
    </div>);

}

function ReadProse({ value, placeholder }) {
  return <div className="ctx-doc rounded-xl border border-[var(--border)] bg-[var(--surface-2)] px-4 py-3 opacity-90">{value ? renderTemplatePreview(value) : <span className="text-[var(--bar)] text-[13px]">{placeholder}</span>}</div>;
}

function LockedDefineBanner({ kind, what }) {
  return (
    <div className="flex items-start gap-2.5 text-[12.5px] text-[var(--text-faint)] bg-[var(--surface-inset)] border border-[#e8ddc2] rounded-xl px-4 py-3">
      <Icon name="shield" size={16} className="shrink-0 mt-px" />
      <span>This {kind} is locked here. The {what} are read-only — head to <b>Design the output</b> to modify its template, or duplicate it for a fully editable copy.</span>
    </div>);

}

function SkillDefineStep({ item, update, ws, locked }) {
  return (
    <div className="flex flex-col gap-7 max-w-[760px]">
      {locked && <LockedDefineBanner kind="skill" what="description and instructions" />}
      {item.availability &&
      <BuilderField label="Availability" hint="what must be connected for this skill to run">
          <AvailabilityNote text={item.availability} />
        </BuilderField>
      }
      <BuilderField label="Description" hint="matched against requests to decide WHEN this skill runs">
        {locked ? <ReadProse value={item.desc} placeholder="No description." /> :
        <ProseSection value={item.desc} onChange={(v) => update({ desc: v })} placeholder="When the user asks to draft a ticket or write a story, use this skill to…" />}
      </BuilderField>
      <BuilderField label="Instructions" hint="how the skill works, step by step">
        {locked ? <ReadProse value={item.instructions} placeholder="No instructions." /> :
        <ProseSection value={item.instructions} onChange={(v) => update({ instructions: v })} placeholder="Describe the steps, what good output looks like, and edge cases…" />}
      </BuilderField>
      <div className="flex items-start gap-2.5 text-[12px] text-[var(--text-faint)] bg-[var(--surface-2)] border border-[var(--border)] rounded-xl px-4 py-3">
        <Icon name="robot" size={15} className="shrink-0 mt-0.5 text-[var(--text-faint2)]" />
        <span>Sub-agents are picked automatically at runtime — every skill has access to all available sub-agents. Just describe the work in the instructions; the right sub-agents are chosen for you.</span>
      </div>
    </div>);

}

function AgentDefineStep({ item, update }) {
  return (
    <div className="flex flex-col gap-7 max-w-[760px]">
      <div className="flex items-start gap-2.5 text-[12.5px] text-[var(--text-2)] bg-[var(--accent-tint)] border border-[var(--accent)]/30 rounded-xl px-4 py-3">
        <Icon name="sparkles" size={16} className="shrink-0 mt-0.5 text-[var(--accent)]" />
        <span>Sub-agents investigate and return findings to the main thread — they don't choose the user-facing format. The calling skill owns the output.</span>
      </div>
      <BuilderField label="Description" hint="used to decide WHEN a skill picks this agent">
        <ProseSection value={item.desc} onChange={(v) => update({ desc: v })} placeholder="Traces architecture, ownership, and dependencies across the connected repositories…" />
      </BuilderField>
      <BuilderField label="Instructions / prompt" hint="how the agent investigates and what it returns">
        <ProseSection value={item.instructions} onChange={(v) => update({ instructions: v })} placeholder="You are an investigator. Locate the relevant context and return structured findings…" />
      </BuilderField>
      <BuilderField label="Model" hint="optional override — defaults to the chat's model">
        <AgentModelPicker value={item.model} onChange={(v) => update({ model: v })} />
      </BuilderField>
    </div>);

}

function SkillDesignStep({ item, update, locked }) {
  const designUpdate = locked ? (p) => update({ ...p, templateOverridden: true }) : update;
  const [docTab, setDocTab] = useState("preview");
  const bodyTypes = item.bodyTypes || null;
  const [subType, setSubType] = useState(bodyTypes ? bodyTypes[0] : null);
  const activeBody = bodyTypes ? (item.bodyByType && item.bodyByType[subType] || {}) : null;
  const curTemplate = activeBody ? (activeBody.template || "") : (item.bodyTemplate || "");
  const curExample = activeBody ? (activeBody.example || activeBody.template || "") : (item.bodyExample || item.bodyTemplate);
  const writeTemplate = (v) => bodyTypes
    ? designUpdate({ bodyByType: { ...item.bodyByType, [subType]: { ...(item.bodyByType && item.bodyByType[subType] || {}), template: v } } })
    : designUpdate({ bodyTemplate: v });
  const picker =
  <BuilderField label="Output format" hint="what the user receives when the skill runs">
      {locked ? <OutputBadge output={item.output} /> : <OutputSelector value={item.output} onChange={(output) => update({ output })} />}
    </BuilderField>;

  let body;
  if (item.output === "none")
  body =
  <div className="max-w-[640px] rounded-xl border border-dashed border-[var(--line)] bg-[var(--surface-2)] px-6 py-12 text-center">
        <span className="w-12 h-12 rounded-xl flex items-center justify-center bg-[var(--surface-inset)] text-[var(--bar)] mb-4 mx-auto"><Icon name="sparkles" size={24} /></span>
        <div className="text-[15px] font-semibold text-[var(--text)]">Nothing to design</div>
        <p className="text-[13px] text-[var(--text-faint)] mt-1.5 max-w-[400px] mx-auto leading-relaxed">Output is <b>Dynamic</b> — the agent picks the best format at runtime. Pick <b>Markdown</b>, <b>HTML</b>, or <b>Widget</b> above to design a fixed output instead.</p>
      </div>;else

  if (item.output === "widget")
  body = item.templatableBody ?
  <div className="max-w-[980px] flex flex-col gap-4">
        {locked && <div className="text-[12px] text-[var(--text-faint)] flex items-center gap-1.5"><Icon name="edit-line" size={13} className="text-[var(--accent)]" /> Modifying the ticket body template — the widget form and logic stay inherited.</div>}
        <div className="flex items-start gap-2.5 text-[12.5px] text-[var(--text-2)] bg-[var(--accent-tint)] border border-[var(--accent)]/30 rounded-xl px-4 py-3">
          <Icon name="grid" size={16} className="shrink-0 mt-0.5 text-[var(--accent)]" />
          <span>The interactive ticket form (<code className="font-mono text-[11.5px]">{item.widgetTool}</code>) is fixed. What you design here is the <b>ticket body</b> — the Markdown description written into every drafted ticket. {bodyTypes ? <>Each issue type gets its own template; conventions differ company to company, so these are yours to shape.</> : <>Story conventions differ company to company, so this template is yours to shape.</>}</span>
        </div>
        {bodyTypes &&
        <div className="flex items-center gap-1.5 flex-wrap">
          {bodyTypes.map((t) =>
        <button key={t} onClick={() => setSubType(t)} className={`flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-[12.5px] font-medium border transition-colors ${subType === t ? "bg-[var(--accent-tint)] border-[var(--accent)]/40 text-[var(--accent)]" : "bg-[var(--card)] border-[var(--border)] text-[var(--text-muted)] hover:text-[var(--text)]"}`}><Icon name={t === "Story" ? "story" : t === "Epic" ? "hierarchy" : t === "Bug" ? "target" : "check"} size={13} /> {t}</button>
        )}
        </div>}
        <div className="rounded-xl border border-[var(--border)] bg-[var(--card)] p-4 flex flex-col gap-3.5">
          <div className="inline-flex items-center bg-[var(--border-soft)] rounded-lg p-0.5 w-fit">
            {[["preview", "Preview", "eye"], ["structure", "Structure", "file"]].map(([k, lbl, ic]) =>
        <button key={k} onClick={() => setDocTab(k)} className={`flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-[12px] font-medium whitespace-nowrap ${docTab === k ? "bg-[var(--card)] shadow-sm text-[var(--text)]" : "text-[var(--text-muted)]"}`}><Icon name={ic} size={12} /> {lbl}</button>
        )}
          </div>
          {docTab === "preview" ?
      <PreviewPane label={bodyTypes ? `${subType} body · example` : "Ticket body · example"}><div className="ctx-doc">{renderTemplatePreview(curExample)}</div></PreviewPane> :
      <>
                <div className="rounded-lg border border-[var(--border)] overflow-hidden">
                  <div className="px-3 py-2 border-b border-[var(--border-soft)] bg-[var(--surface-2)] flex items-center gap-2 text-[11.5px] text-[var(--text-faint2)]"><Icon name="file" size={12} /> {bodyTypes ? `${subType.toLowerCase()}-body.md` : "ticket-body.md"}</div>
                  <textarea value={curTemplate} onChange={(e) => writeTemplate(e.target.value)} rows={15} placeholder={"## User Story\n{As a [role], I want…}"}
          className="w-full resize-none px-3 py-2.5 text-[12px] font-mono text-[var(--text)] bg-transparent outline-none leading-relaxed placeholder:text-[var(--bar)]" />
                </div>
                <p className="text-[11px] text-[var(--text-faint2)]">Use <code className="font-mono">{"{curly}"}</code> for content the skill fills per ticket; static headings stay fixed. The Preview tab shows one drafted example.</p>
              </>}
        </div>
      </div> :
  item.bespoke ?
  <div className="max-w-[640px] rounded-xl border border-dashed border-[var(--line)] bg-[var(--surface-2)] px-6 py-12 text-center">
        <span className="w-12 h-12 rounded-xl flex items-center justify-center bg-[var(--surface-inset)] text-[var(--bar)] mb-4 mx-auto"><Icon name="grid" size={24} /></span>
        <div className="text-[15px] font-semibold text-[var(--text)]">Built-in widget</div>
        <p className="text-[13px] text-[var(--text-faint)] mt-1.5 max-w-[420px] mx-auto leading-relaxed">This skill renders through <code className="font-mono text-[12px] bg-[var(--surface-inset)] px-1.5 py-0.5 rounded">{item.widgetTool}</code> — a bespoke widget that isn't templatable yet. Nothing to design here.</p>
      </div> :

  <div className="max-w-[980px] flex flex-col gap-3">
        {locked && <div className="text-[12px] text-[var(--text-faint)] flex items-center gap-1.5"><Icon name="edit-line" size={13} className="text-[var(--accent)]" /> Modifying the widget for this skill — the logic stays inherited.</div>}
        <WidgetEditor skill={item} update={designUpdate} />
      </div>;else

  {
    const on = !!item.useTemplate;
    const isHtml = item.output === "html";
    const kindLabel = isHtml ? "HTML" : "Markdown";
    const docTabs = [["preview", "Preview", "eye"], ["structure", "Structure", isHtml ? "code" : "file"]];
    body =
    <div className="max-w-[980px] flex flex-col gap-4">
        {locked && on && <div className="text-[12px] text-[var(--text-faint)] flex items-center gap-1.5"><Icon name="edit-line" size={13} className="text-[var(--accent)]" /> Modifying the structure — the logic stays inherited.</div>}
        <div className="flex items-start justify-between gap-4 rounded-xl border border-[var(--border)] bg-[var(--card)] px-4 py-3">
          <div className="min-w-0">
            <div className="text-[13.5px] font-medium text-[var(--text)]">Define a structure</div>
            <p className="text-[12px] text-[var(--text-faint2)] mt-0.5 leading-snug">{on ?
            isHtml ?
            "The skill follows this outline and generates styled HTML from it each run." :
            "The skill follows this Markdown outline, filling each section per run." :
            `Off — the agent writes the ${kindLabel} freely each run, guided only by the instructions.`}</p>
          </div>
          <SettingsToggle on={on} onChange={(v) => designUpdate({ useTemplate: v })} />
        </div>
        {on &&
      <div className="rounded-xl border border-[var(--border)] bg-[var(--card)] p-4 flex flex-col gap-3.5">
            <div className="inline-flex items-center bg-[var(--border-soft)] rounded-lg p-0.5 w-fit max-w-full overflow-x-auto">
              {docTabs.map(([k, lbl, ic]) =>
          <button key={k} onClick={() => setDocTab(k)} className={`flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-[12px] font-medium whitespace-nowrap ${docTab === k ? "bg-[var(--card)] shadow-sm text-[var(--text)]" : "text-[var(--text-muted)]"}`}><Icon name={ic} size={12} /> {lbl}</button>
          )}
            </div>
            {docTab === "preview" &&
        <PreviewPane label={isHtml ? "Example output · HTML" : "Example output"}>{isHtml ?
          <div className="ctx-doc" dangerouslySetInnerHTML={{ __html: item.example || "" }} /> :
          <div className="ctx-doc">{renderTemplatePreview(item.example || item.template)}</div>}</PreviewPane>
        }
            {docTab === "structure" && <>
              <div className="rounded-lg border border-[var(--border)] overflow-hidden">
                <div className="px-3 py-2 border-b border-[var(--border-soft)] bg-[var(--surface-2)] flex items-center justify-between gap-2 text-[11.5px] text-[var(--text-faint2)]">
                  <span className="flex items-center gap-2"><Icon name="file" size={12} /> structure.md</span>
                  {isHtml && <span className="inline-flex items-center gap-1 text-[10.5px] text-[var(--text-faint2)]"><Icon name="sparkles" size={10} className="text-[var(--accent)]" /> rendered as HTML at runtime</span>}
                </div>
                <textarea value={item.structure || item.template || ""} onChange={(e) => designUpdate(isHtml ? { structure: e.target.value } : { template: e.target.value })} rows={16} placeholder={"# {Title}\n\n## Section\n{describe what goes here}"}
            className="w-full resize-none px-3 py-2.5 text-[12px] font-mono text-[var(--text)] bg-transparent outline-none leading-relaxed placeholder:text-[var(--bar)]" />
              </div>
              <p className="text-[11px] text-[var(--text-faint2)]">{isHtml ?
            <>The outline only describes the structure — the skill writes the actual HTML dynamically each run, so every report fits its content. The Preview tab shows one rendered example.</> :
            <>Use <code className="font-mono">{"{curly}"}</code> for content-descriptions — the skill fills them per run; everything outside stays fixed.</>}</p>
            </>}
          </div>
      }
      </div>;

  }
  return (
    <div className="flex flex-col gap-6">
      {picker}
      <div className="border-t border-[var(--border-soft)] pt-6">{body}</div>
    </div>);

}

function SkillArtifactStep({ item, update, locked }) {
  const on = !!item.createsArtifact;
  const defaultType = item.artifactType || (item.output === "widget" ? "Result" : item.name);
  return (
    <div className="flex flex-col gap-6 max-w-[760px]">
      <div className="flex items-start justify-between gap-4 rounded-xl border border-[var(--border)] bg-[var(--card)] px-4 py-3.5">
        <div className="min-w-0">
          <div className="text-[13.5px] font-medium text-[var(--text)]">Create an artifact</div>
          <p className="text-[12.5px] text-[var(--text-faint2)] mt-0.5 leading-snug max-w-[560px]">When on, every run is saved as a typed artifact in Teklens — body, embedding and metadata in Qdrant. When off, the run is just output you can turn into a memory anytime.</p>
        </div>
        {locked ?
        <span className="inline-flex items-center gap-1.5 rounded-full border border-[var(--border)] bg-[var(--surface-2)] px-2.5 py-1 text-[11.5px] font-medium text-[var(--text-muted)]"><Icon name="shield" size={12} /> {on ? "On" : "Off"}</span> :
        <SettingsToggle on={on} onChange={(v) => update({ createsArtifact: v, artifactType: v ? item.artifactType || defaultType : item.artifactType })} />}
      </div>

      {on ?
      <>
          <BuilderField label="Artifact type" hint="the category — Story, Release Note, PRD, ADR… (the title is generated per run)">
            {locked ?
          <div className="rounded-lg border border-[var(--border)] bg-[var(--surface-2)] px-3.5 py-2.5 text-[13.5px] font-medium text-[var(--text)] flex items-center gap-2 w-fit"><Icon name="file" size={14} className="text-[var(--violet-ink)]" /> {item.artifactType}</div> :
          <div className="flex items-center gap-2 rounded-lg border border-[var(--border)] bg-[var(--card)] px-3.5 py-2.5 max-w-[420px] focus-within:border-[var(--violet-ink)]">
                  <Icon name="file" size={15} className="text-[var(--violet-ink)] shrink-0" />
                  <input value={item.artifactType || ""} onChange={(e) => update({ artifactType: e.target.value })} placeholder={defaultType}
            className="flex-1 bg-transparent text-[13.5px] font-medium text-[var(--text)] outline-none placeholder:text-[var(--bar)] placeholder:font-normal" />
                </div>}
          </BuilderField>
          <div className="rounded-xl border border-[color-mix(in_srgb,var(--violet-ink)_24%,transparent)] bg-[var(--violet-tint)] px-4 py-3.5 flex flex-col gap-2.5">
            <div className="flex items-center gap-2.5">
              <span className="w-9 h-9 rounded-lg flex items-center justify-center shrink-0 bg-[var(--card)] text-[var(--violet-ink)]"><Icon name="file" size={16} /></span>
              <div>
                <div className="text-[13.5px] font-semibold text-[var(--text)]">{item.artifactType || defaultType} <span className="text-[var(--text-faint2)] font-normal">· {item.output === "none" ? "text" : item.output} body</span></div>
                <div className="text-[11.5px] text-[var(--text-faint2)]">Lives in Teklens · title generated per run · searchable &amp; pinnable</div>
              </div>
            </div>
          </div>
        </> :

      <div className="rounded-xl border border-dashed border-[var(--line)] bg-[var(--surface-2)] px-6 py-10 text-center">
          <span className="w-12 h-12 rounded-xl flex items-center justify-center bg-[var(--surface-inset)] text-[var(--bar)] mb-3.5 mx-auto"><Icon name="message" size={22} /></span>
          <div className="text-[14px] font-semibold text-[var(--text)]">No artifact</div>
          <p className="text-[12.5px] text-[var(--text-faint)] mt-1.5 max-w-[420px] mx-auto leading-relaxed">The skill's result stays as conversation output. The user can promote any run to a memory when it's worth keeping.</p>
        </div>
      }
    </div>);

}

function GuidedBuilder({ ws, kind, item, onBack }) {
  const isSkill = kind === "skill";
  const update = (patch) => isSkill ?
  ws.setSkills((xs) => xs.map((x) => x.id === item.id ? { ...x, ...patch } : x)) :
  ws.setAgents((xs) => xs.map((x) => x.id === item.id ? { ...x, ...patch } : x));
  const [model, setModel] = useState(item.model && item.model !== "Current Conversation model" ? item.model : "Current Conversation model");
  const locked = saLockState(item, ws.scope).locked;
  const steps = isSkill ?
  [{ id: "define", label: "Build the skill", short: "Build" }, { id: "design", label: "Design the output", short: "Design" }, { id: "artifact", label: "Create artifact", short: "Artifact" }] :
  [{ id: "define", label: "Build the agent", short: "Build" }];
  const [step, setStep] = useState(locked && isSkill ? "design" : "define");
  const idx = steps.findIndex((s) => s.id === step);
  const last = idx === steps.length - 1;
  const done = () => ws.setSaMode("detail");
  const allList = () => {isSkill ? ws.setSkillSel(null) : ws.setAgentSel(null);};
  const onDelete = () => {if (isSkill) {ws.setSkills((xs) => xs.filter((x) => x.id !== item.id));ws.setSkillSel(null);} else {ws.setAgents((xs) => xs.filter((x) => x.id !== item.id));ws.setAgentSel(null);}};

  return (
    <div className="flex-1 min-w-0 flex flex-col bg-[var(--surface)]">
      <div className="flex-1 min-h-0 flex">
        <BuilderChat key={item.id} item={item} kind={kind} model={model} setModel={setModel} step={step} onRename={(name) => !locked && update({ name })} />
        {/* right pane — stepped */}
        <div className="flex-1 min-w-0 flex flex-col bg-[var(--card)]">
          <BuilderStepper steps={steps} step={step} setStep={setStep}
          right={<button onClick={done} className="flex items-center gap-1.5 px-3.5 py-1.5 rounded-lg bg-[var(--accent)] text-white text-[12.5px] font-medium hover:brightness-110 shadow-[0_1px_0_rgba(0,0,0,0.08)]"><Icon name="check" size={14} /> Done</button>} />
          <div className="flex-1 min-h-0 overflow-y-auto px-6 py-6">
            {step === "define" && (isSkill ?
            <SkillDefineStep item={item} update={update} ws={ws} locked={locked} /> :
            <AgentDefineStep item={item} update={update} />)}
            {step === "design" && <SkillDesignStep item={item} update={update} locked={locked} />}
            {step === "artifact" && <SkillArtifactStep item={item} update={update} locked={locked} />}
          </div>
          {/* footer nav */}
          <div className="shrink-0 border-t border-[var(--border-soft)] px-6 py-3 flex items-center">
            {!locked ?
            <button onClick={onDelete} className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-[12.5px] text-[var(--amber-ink)] hover:bg-[var(--amber-ink)]/[0.07]"><Icon name="trash" size={14} /> Delete</button> :
            <span />}
            <div className="ml-auto flex items-center gap-2">
              {idx > 0 && <button onClick={() => setStep(steps[idx - 1].id)} className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-[12.5px] font-medium text-[var(--text-2)] bg-[var(--card)] border border-[var(--border)] hover:bg-[var(--surface-2)]"><Icon name="chevron-left" size={14} /> Back</button>}
              {!last ?
              <button onClick={() => setStep(steps[idx + 1].id)} className="flex items-center gap-1.5 px-3.5 py-1.5 rounded-lg bg-[var(--accent)] text-white text-[12.5px] font-medium hover:brightness-110 shadow-[0_1px_0_rgba(0,0,0,0.08)]">Next: {steps[idx + 1].label} <Icon name="chevron-right" size={14} /></button> :
              <button onClick={done} className="flex items-center gap-1.5 px-3.5 py-1.5 rounded-lg bg-[var(--accent)] text-white text-[12.5px] font-medium hover:brightness-110 shadow-[0_1px_0_rgba(0,0,0,0.08)]"><Icon name="check" size={14} /> Save &amp; close</button>}
            </div>
          </div>
        </div>
      </div>
    </div>);

}

function BuilderTabContent({ tab, kind, item, update, ws, onDelete }) {
  if (tab === "preview") return <BuilderPreview kind={kind} item={item} ws={ws} />;

  if (tab === "skill") return (
    <div className="flex flex-col gap-7 max-w-[760px]">
      <BuilderField label="Description" hint="matched against requests to decide WHEN this skill runs">
        <ProseSection value={item.desc} onChange={(v) => update({ desc: v })} placeholder="When the user provides a product idea or feature concept, use this skill to…" />
      </BuilderField>
      <BuilderField label="Instructions" hint="how the skill works">
        <ProseSection value={item.instructions} onChange={(v) => update({ instructions: v })} placeholder="Describe the steps, what good output looks like, and edge cases…" />
      </BuilderField>
      <BuilderField label="Output">
        <OutputSelector value={item.output} onChange={(output) => update({ output })} />
      </BuilderField>
    </div>);


  if (tab === "agents") return (
    <div className="max-w-[760px]">
      <BuilderField label="Sub-Agents used" hint="reusable sub-agents this skill calls — 0..n">
        <AgentMultiSelect ws={ws} value={item.agents || []} onChange={(agents) => update({ agents })} />
      </BuilderField>
    </div>);


  if (tab === "agent") return (
    <div className="max-w-[760px]">
      <BuilderField label="Agent prompt" hint="how the agent investigates and what it returns">
        <ProseSection value={item.instructions} onChange={(v) => update({ instructions: v })} placeholder="You are an investigator. Locate the relevant context and return structured findings…" />
      </BuilderField>
    </div>);


  if (tab === "tools") return (
    <div className="flex flex-col gap-7 max-w-[600px]">
      <BuilderField label="Model"><AgentModelPicker value={item.model} onChange={(v) => update({ model: v })} /></BuilderField>
      <BuilderField label="Tools" hint="abilities the agent may use">
        <div className="flex flex-wrap gap-1.5">
          {SA_TOOLS.map((t) => {
            const on = (item.tools || []).includes(t);
            return <button key={t} onClick={() => update({ tools: on ? item.tools.filter((x) => x !== t) : [...(item.tools || []), t] })}
            className={`flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg text-[12px] font-medium border ${on ? "border-[var(--accent)]/40 bg-[var(--accent)]/[0.08] text-[var(--accent)]" : "border-[var(--border)] bg-[var(--card)] text-[var(--text-muted)] hover:border-[var(--line)]"}`}>{on && <Icon name="check" size={12} />} {t}</button>;
          })}
        </div>
      </BuilderField>
      <button onClick={onDelete} className="flex items-center gap-1.5 px-3 py-2 rounded-lg text-[13px] text-[var(--amber-ink)] hover:bg-[var(--amber-ink)]/[0.07] w-fit"><Icon name="trash" size={14} /> Delete agent</button>
    </div>);


  if (tab === "data") {
    if (item.output !== "widget") return (
      <div className="max-w-[640px] rounded-xl border border-dashed border-[var(--line)] bg-[var(--surface-2)] px-6 py-10 text-center">
        <div className="text-[14px] font-medium text-[var(--text)]">No data structure</div>
        <p className="text-[12.5px] text-[var(--text-faint)] mt-1.5">Data structures apply to <b>Widget</b> output. Switch output to Widget on the Skill tab to define a schema and sample data.</p>
      </div>);

    return (
      <div className="flex flex-col gap-5 max-w-[820px]">
        <BuilderField label="Data structure (schema)"><WidgetCode value={item.schema} onChange={(v) => update({ schema: v })} file="schema.json" /></BuilderField>
        <BuilderField label="Sample data"><WidgetCode value={item.sample} onChange={(v) => update({ sample: v })} file="sample.json" /></BuilderField>
      </div>);

  }

  if (tab === "template") {
    if (item.output === "widget") return (
      <div className="max-w-[820px]"><BuilderField label="Widget visual template (HTML)"><WidgetCode value={item.widgetHtml} onChange={(v) => update({ widgetHtml: v })} file="widget.html" /></BuilderField></div>);

    if (item.output === "none") return (
      <div className="max-w-[640px] rounded-xl border border-dashed border-[var(--line)] bg-[var(--surface-2)] px-6 py-10 text-center">
        <div className="text-[14px] font-medium text-[var(--text)]">No template</div>
        <p className="text-[12.5px] text-[var(--text-faint)] mt-1.5">This skill replies as normal chat. Set output to Markdown, HTML, or Widget to add a template.</p>
      </div>);

    return (
      <div className="grid grid-cols-1 xl:grid-cols-2 gap-4 max-w-[980px]">
        <div className="rounded-xl border border-[var(--border)] overflow-hidden">
          <div className="px-3 py-2 border-b border-[var(--border-soft)] bg-[var(--surface-2)] flex items-center gap-2 text-[11.5px] text-[var(--text-faint2)]"><Icon name={item.output === "html" ? "code" : "file"} size={12} /> template.{item.output === "html" ? "html" : "md"}</div>
          <textarea value={item.template || ""} onChange={(e) => update({ template: e.target.value })} rows={16} placeholder={"# {Title}\n\n## Section\n{describe what goes here}"}
          className="w-full resize-none px-3 py-2.5 text-[12px] font-mono text-[var(--text)] bg-transparent outline-none leading-relaxed placeholder:text-[var(--bar)]" />
        </div>
        <PreviewPane><div className="ctx-doc">{renderTemplatePreview(item.template)}</div></PreviewPane>
      </div>);

  }
  return null;
}

function BuilderField({ label, hint, children }) {
  return (
    <div>
      <div className="flex items-baseline gap-2 mb-2.5">
        <span className="text-[13px] font-semibold text-[var(--text)]">{label}</span>
        {hint && <span className="text-[11.5px] text-[var(--text-faint2)]">{hint}</span>}
      </div>
      {children}
    </div>);

}

function BuilderPreview({ kind, item, ws }) {
  if (kind === "agent" || item.output === "none" || !item.output) {
    return (
      <div className="max-w-[760px]">
        <div className="flex items-center gap-2 flex-wrap mb-4">
          <span className="text-[17px] font-semibold text-[var(--text)]">{item.name}</span>
          {kind === "skill" && <OutputBadge output={item.output} />}
          <LineageBadge lineage={saEffLineage(item, ws.scope)} />
        </div>
        <p className="text-[13.5px] text-[var(--text-3)] leading-relaxed mb-5">{item.desc || "No description yet — describe it in the chat to get started."}</p>
        <div className="ctx-doc">{renderTemplatePreview(item.instructions)}</div>
      </div>);

  }
  if (item.output === "widget") {
    let data = null,ok = true;try {data = JSON.parse(item.sample || "{}");} catch (e) {ok = false;}
    return <div className="max-w-[640px]"><PreviewPane label="Widget preview · sample data"><WidgetSamplePreview data={data} ok={ok} /></PreviewPane></div>;
  }
  return <div className="max-w-[680px]"><PreviewPane label="Output preview"><div className="ctx-doc">{renderTemplatePreview(item.template)}</div></PreviewPane></div>;
}