// Config — read-only YAML viewer with redaction + collapsible sections.
const { Card } = window.UI;

const REDACT_KEYS = /^(api_key|api_secret|token|webhook|password|secret)$/i;

function highlightYaml(line) {
  // crude but works: comment, key:value, list, redacted strings
  if (/^\s*#/.test(line)) return <span className="text-ink-3">{line}</span>;
  const m = line.match(/^(\s*)([-]?\s*)([\w._-]+)(\s*:\s*)(.*)$/);
  if (m) {
    const [, indent, dash, key, sep, val] = m;
    const isSecret = REDACT_KEYS.test(key);
    return (
      <>
        <span>{indent}</span>
        {dash && <span className="text-ink-3">{dash}</span>}
        <span className="text-inf-0">{key}</span>
        <span className="text-ink-3">{sep}</span>
        {val === '***REDACTED***' || isSecret && /REDACTED/.test(val)
          ? <span className="text-amb-0">{val}</span>
          : /^\[.*\]$/.test(val)
            ? <span className="text-pos-0">{val}</span>
            : /^-?\d+\.?\d*$/.test(val)
              ? <span className="text-ink-0 num">{val}</span>
              : <span className="text-ink-0">{val}</span>}
      </>
    );
  }
  const li = line.match(/^(\s*)(-\s+)(.*)$/);
  if (li) return <><span>{li[1]}</span><span className="text-ink-3">{li[2]}</span><span className="text-ink-0">{li[3]}</span></>;
  return <span>{line}</span>;
}

function parseSections(yaml) {
  const lines = yaml.split('\n');
  const sections = [];
  let cur = null;
  lines.forEach((l, i) => {
    if (/^\w/.test(l)) {
      if (cur) sections.push(cur);
      cur = { name: l.replace(':', ''), lines: [{ n: i+1, text: l }] };
    } else if (cur) {
      cur.lines.push({ n: i+1, text: l });
    }
  });
  if (cur) sections.push(cur);
  return sections;
}

function PageConfig() {
  const { data, error, loading, refresh } = window.API.useAPI(
    () => window.API.get('/api/v1/config'),
    [],
  );
  const yaml = (data && data.yaml) || '';
  const path = (data && data.path) || 'configs/bot.yaml';
  const redacted = !!(data && data.redacted);
  const note = data && (data.note || data.error);

  const sections = React.useMemo(() => parseSections(yaml || ''), [yaml]);
  const [openSet, setOpenSet] = React.useState(() => new Set(['app']));
  const toggle = (n) => setOpenSet(s => { const c = new Set(s); c.has(n) ? c.delete(n) : c.add(n); return c; });
  const expandAll = () => setOpenSet(new Set(sections.map(s => s.name)));
  const collapseAll = () => setOpenSet(new Set());

  return (
    <div className="p-4 space-y-4">
      <div className="flex items-end justify-between">
        <div>
          <h1 className="text-[16px] font-medium text-ink-0">config</h1>
          <p className="mono text-[11px] text-ink-3 mt-0.5">read-only view of <span className="text-ink-1">{path}</span></p>
        </div>
        <div className="flex gap-px">
          <button onClick={refresh} className="px-2 h-7 mono text-[11px] uppercase tracking-[0.1em] border border-line-0 text-ink-2 hover:text-ink-0 hover:bg-bg-2">refresh</button>
          <button onClick={expandAll} className="px-2 h-7 mono text-[11px] uppercase tracking-[0.1em] border border-line-0 text-ink-2 hover:text-ink-0 hover:bg-bg-2">expand all</button>
          <button onClick={collapseAll} className="px-2 h-7 mono text-[11px] uppercase tracking-[0.1em] border border-line-0 text-ink-2 hover:text-ink-0 hover:bg-bg-2">collapse all</button>
        </div>
      </div>

      <div className="bg-amb-1/10 border border-amb-1/30 px-4 py-3 flex items-start gap-3">
        <Icon.Info size={14} className="text-amb-0 mt-0.5"/>
        <div className="text-[12px] text-ink-1 leading-relaxed">
          secrets are env-only; this view is read-only — to change, edit <span className="mono text-amb-0">{path}</span> on disk and restart.
          <span className="mono text-ink-3"> {redacted ? 'server-side redaction active' : 'no redaction applied'}</span>
        </div>
      </div>

      {loading && <div className="mono text-[11px] text-ink-3">loading…</div>}
      {error && <div className="bg-neg-2/30 border border-neg-1/40 p-3 mono text-[11px] text-neg-0">{error.message}</div>}
      {note && <div className="bg-bg-2 border border-line-0 px-3 py-2 mono text-[11px] text-ink-2">{note}</div>}

      {!loading && !error && yaml && (
        <Card padded={false}>
          <div className="divide-y divide-line-0">
            {sections.map(sec => {
              const open = openSet.has(sec.name);
              return (
                <div key={sec.name}>
                  <button onClick={() => toggle(sec.name)} className="w-full flex items-center gap-2 px-3 py-2 hover:bg-bg-2/40 text-left">
                    {open ? <Icon.ChevronDown size={12} className="text-ink-3"/> : <Icon.ChevronRight size={12} className="text-ink-3"/>}
                    <span className="mono text-[12px] text-inf-0">{sec.name}</span>
                    <span className="mono text-[10.5px] text-ink-3">{sec.lines.length - 1} lines</span>
                  </button>
                  {open && (
                    <pre className="bg-bg-0 border-t border-line-0 mono text-[12px] leading-[1.55] overflow-x-auto scrollbar">
                      {sec.lines.map((l, i) => (
                        <div key={i} className="flex hover:bg-bg-2/30">
                          <span className="select-none px-3 py-0 text-right text-ink-4 w-12 shrink-0 border-r border-line-0">{l.n}</span>
                          <span className="px-3 py-0 whitespace-pre">{highlightYaml(l.text) || ' '}</span>
                        </div>
                      ))}
                    </pre>
                  )}
                </div>
              );
            })}
          </div>
        </Card>
      )}
    </div>
  );
}

window.PageConfig = PageConfig;
