<script lang="ts">
  import { store } from '../store.svelte';
  import {
    analyze,
    autoOptimize,
    setDirection,
    type Fix,
    type FlowNode,
  } from '../optimize';

  // Re-analyse whenever the source changes; pure & cheap.
  const a = $derived(analyze(store.content));

  const DIRECTIONS = ['TB', 'LR', 'BT', 'RL'];

  // Nodes for the focus picker, hubs first.
  const focusable = $derived.by<FlowNode[]>(() => {
    if (!a.graph) return [];
    return [...a.graph.nodes.values()].sort(
      (x, y) => y.inDeg + y.outDeg - (x.inDeg + x.outDeg)
    );
  });

  function applyFix(f: Fix) {
    if (!f.apply) return;
    store.applySource(f.apply(store.content));
    store.notify(`Applied — ${f.title}`, 'success');
  }

  function runAuto() {
    store.applySource(autoOptimize(store.content));
    store.notify('Applied all safe optimizations', 'success');
  }

  function setDir(d: string) {
    if (a.graph?.direction === d) return;
    store.applySource(setDirection(store.content, d));
  }

  function focus(id: string) {
    store.focusNode = store.focusNode === id ? null : id;
    if (store.focusNode && store.layout === 'code') store.layout = 'split';
  }
</script>

<aside class="optimize">
  <header class="head">
    <span class="title">✨ Optimize</span>
    <button
      class="ghost icon"
      title="Close"
      onclick={() => (store.showOptimize = false)}>✕</button
    >
  </header>

  {#if !store.activeId || !store.content.trim()}
    <div class="notice faint">Open a diagram to analyse it.</div>
  {:else if !a.supported}
    <div class="notice">
      <div class="muted">Decluttering is built for flowcharts & state diagrams.</div>
      <p class="faint">
        This looks like a <code>{a.kind || 'different'}</code> diagram, which
        can't be analysed here yet.
      </p>
    </div>
  {:else if a.metrics && a.graph}
    <!-- Readability score -->
    <div class="score-row">
      <div class="gauge" data-rating={a.rating.toLowerCase()}>
        <span class="num">{a.score}</span>
      </div>
      <div class="score-meta">
        <div class="rating" data-rating={a.rating.toLowerCase()}>{a.rating}</div>
        <div class="faint">readability score</div>
        {#if a.graph.usesElk}<div class="elk-badge">ELK layout on</div>{/if}
      </div>
    </div>

    <button
      class="primary auto"
      onclick={runAuto}
      disabled={a.fixes.filter((f) => f.apply).length === 0}
    >
      Auto-optimize ✦
    </button>

    <!-- Metrics -->
    <div class="metrics">
      <div class="metric"><b>{a.metrics.nodes}</b><span>nodes</span></div>
      <div class="metric"><b>{a.metrics.edges}</b><span>edges</span></div>
      <div class="metric"><b>{a.metrics.density.toFixed(1)}</b><span>edges/node</span></div>
      <div class="metric"><b>{a.metrics.maxDegree}</b><span>busiest hub</span></div>
      <div class="metric"><b>{a.metrics.interGroupEdges}</b><span>cross-group</span></div>
      <div class="metric"><b>{a.metrics.subgraphs}</b><span>groups</span></div>
    </div>

    <!-- Layout direction -->
    <div class="dir">
      <span class="lbl faint">Direction</span>
      <div class="seg">
        {#each DIRECTIONS as d}
          <button class:on={a.graph.direction === d} onclick={() => setDir(d)}>{d}</button>
        {/each}
      </div>
    </div>

    <!-- Suggested fixes -->
    <div class="section-head">Suggestions</div>
    <div class="fixes">
      {#each a.fixes as f (f.id)}
        <div class="fix" data-sev={f.severity}>
          <div class="fix-head">
            <span class="dot"></span>
            <span class="fix-title">{f.title}</span>
            {#if f.apply}
              <button class="apply" onclick={() => applyFix(f)}>Apply</button>
            {:else}
              <span class="tag">tip</span>
            {/if}
          </div>
          <p class="fix-detail">{f.detail}</p>
        </div>
      {/each}
      {#if a.fixes.length === 0}
        <div class="clean faint">✓ Nothing to declutter — this reads cleanly.</div>
      {/if}
    </div>

    <!-- Focus reader -->
    <div class="section-head">
      Focus a node
      {#if store.focusNode}
        <button class="ghost mini clear" onclick={() => (store.focusNode = null)}>
          clear
        </button>
      {/if}
    </div>
    <p class="hint faint">Spotlight one node and its neighbours in the preview.</p>
    <div class="focus-list">
      {#each focusable.slice(0, 12) as n (n.id)}
        <button
          class="chip"
          class:on={store.focusNode === n.id}
          title={n.label}
          onclick={() => focus(n.id)}
        >
          {n.label}<span class="deg">{n.inDeg + n.outDeg}</span>
        </button>
      {/each}
    </div>
  {/if}
</aside>

<style>
  .optimize {
    width: 312px;
    flex-shrink: 0;
    background: var(--bg-elev);
    border-left: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    overflow-y: auto;
  }
  .head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 10px 10px 14px;
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    background: var(--bg-elev);
    z-index: 2;
  }
  .title {
    font-weight: 600;
    font-size: 13px;
  }
  .notice {
    padding: 18px 14px;
    font-size: 13px;
    line-height: 1.5;
  }
  .notice code {
    font-family: var(--mono);
    color: var(--accent);
  }

  /* Score */
  .score-row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px;
  }
  .gauge {
    width: 60px;
    height: 60px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    flex-shrink: 0;
    border: 3px solid var(--border-strong);
    background: var(--bg-input);
  }
  .gauge .num {
    font-size: 22px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
  }
  .gauge[data-rating='clear'] {
    border-color: var(--green);
  }
  .gauge[data-rating='readable'] {
    border-color: var(--accent);
  }
  .gauge[data-rating='busy'] {
    border-color: var(--amber);
  }
  .gauge[data-rating='tangled'] {
    border-color: var(--red);
  }
  .rating {
    font-weight: 600;
    font-size: 15px;
  }
  .rating[data-rating='clear'] {
    color: var(--green);
  }
  .rating[data-rating='readable'] {
    color: var(--accent);
  }
  .rating[data-rating='busy'] {
    color: var(--amber);
  }
  .rating[data-rating='tangled'] {
    color: var(--red);
  }
  .elk-badge {
    margin-top: 4px;
    display: inline-block;
    font-size: 10px;
    color: var(--green);
    border: 1px solid var(--green);
    border-radius: 3px;
    padding: 1px 5px;
  }
  .auto {
    margin: 0 14px 6px;
    width: calc(100% - 28px);
  }

  /* Metrics */
  .metrics {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    padding: 10px 14px 6px;
  }
  .metric {
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 8px 6px;
    text-align: center;
  }
  .metric b {
    display: block;
    font-size: 17px;
    font-variant-numeric: tabular-nums;
  }
  .metric span {
    font-size: 10.5px;
    color: var(--text-faint);
  }

  /* Direction */
  .dir {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
  }
  .lbl {
    font-size: 12px;
  }
  .seg {
    display: inline-flex;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    overflow: hidden;
  }
  .seg button {
    border: none;
    border-radius: 0;
    background: transparent;
    padding: 5px 9px;
    font-size: 11.5px;
    color: var(--text-dim);
    font-family: var(--mono);
  }
  .seg button:hover {
    background: var(--bg-elev-2);
  }
  .seg button.on {
    background: var(--accent-soft);
    color: var(--text);
  }

  .section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 14px 4px;
    font-size: 11px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-faint);
  }
  .hint {
    margin: 0;
    padding: 0 14px 8px;
    font-size: 11.5px;
    line-height: 1.4;
  }

  /* Fixes */
  .fixes {
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: 2px 14px 6px;
  }
  .fix {
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-left-width: 3px;
    border-radius: var(--radius-sm);
    padding: 9px 10px;
  }
  .fix[data-sev='high'] {
    border-left-color: var(--red);
  }
  .fix[data-sev='medium'] {
    border-left-color: var(--amber);
  }
  .fix[data-sev='low'] {
    border-left-color: var(--text-faint);
  }
  .fix-head {
    display: flex;
    align-items: center;
    gap: 7px;
  }
  .fix-title {
    flex: 1;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.3;
  }
  .apply {
    padding: 3px 10px;
    font-size: 11.5px;
    flex-shrink: 0;
  }
  .tag {
    font-size: 10px;
    color: var(--text-faint);
    border: 1px solid var(--border);
    border-radius: 3px;
    padding: 1px 5px;
    flex-shrink: 0;
  }
  .fix-detail {
    margin: 6px 0 0;
    font-size: 11.5px;
    line-height: 1.45;
    color: var(--text-dim);
  }
  .clean {
    padding: 10px 0;
    font-size: 12.5px;
  }

  /* Focus chips */
  .focus-list {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    padding: 0 14px 16px;
  }
  .chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 100%;
    padding: 4px 6px 4px 9px;
    font-size: 11.5px;
    border-radius: 999px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .chip .deg {
    font-size: 10px;
    color: var(--text-faint);
    background: var(--bg);
    border-radius: 999px;
    padding: 0 5px;
    min-width: 16px;
    text-align: center;
  }
  .chip.on {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
  }
  .chip.on .deg {
    color: #fff;
    background: rgba(255, 255, 255, 0.2);
  }
  .mini {
    padding: 1px 6px;
    font-size: 10px;
    text-transform: none;
    letter-spacing: 0;
  }
  .clear {
    color: var(--accent);
  }
</style>
