/* components.jsx — shared UI for the DeltaBlue SSL Toolkit.
 * Lucide-style stroke icons + layout primitives built on the DeltaBlue
 * design-system components. Exported to window for the tab scripts.
 */
const DS = window.DeltaBlueDesignSystem_b0e437;
const { Button, Card, Badge, Tag } = DS;

/* ---------- icons (Lucide-style, 1.75 stroke, currentColor) ---------- */
function Svg(props) {
  const { size = 18, children, style } = props;
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
      strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" style={style} aria-hidden="true">
      {children}
    </svg>
  );
}
const Icon = {
  Shield: (p) => <Svg {...p}><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></Svg>,
  Link: (p) => <Svg {...p}><path d="M9 17H7A5 5 0 0 1 7 7h2"/><path d="M15 7h2a5 5 0 0 1 0 10h-2"/><line x1="8" y1="12" x2="16" y2="12"/></Svg>,
  Copy: (p) => <Svg {...p}><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></Svg>,
  Check: (p) => <Svg {...p}><polyline points="20 6 9 17 4 12"/></Svg>,
  Upload: (p) => <Svg {...p}><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></Svg>,
  Download: (p) => <Svg {...p}><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></Svg>,
  Search: (p) => <Svg {...p}><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></Svg>,
  Alert: (p) => <Svg {...p}><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></Svg>,
  X: (p) => <Svg {...p}><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></Svg>,
  Clock: (p) => <Svg {...p}><circle cx="12" cy="12" r="9"/><polyline points="12 7 12 12 15 14"/></Svg>,
  Key: (p) => <Svg {...p}><circle cx="7.5" cy="15.5" r="4.5"/><path d="m10.5 12.5 7.5-7.5"/><path d="m16 5 3 3"/><path d="m13.5 7.5 3 3"/></Svg>,
  File: (p) => <Svg {...p}><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></Svg>,
  Globe: (p) => <Svg {...p}><circle cx="12" cy="12" r="9"/><line x1="3" y1="12" x2="21" y2="12"/><path d="M12 3a14 14 0 0 1 0 18 14 14 0 0 1 0-18z"/></Svg>,
  Server: (p) => <Svg {...p}><rect x="3" y="4" width="18" height="7" rx="1.5"/><rect x="3" y="13" width="18" height="7" rx="1.5"/><line x1="7" y1="7.5" x2="7.01" y2="7.5"/><line x1="7" y1="16.5" x2="7.01" y2="16.5"/></Svg>,
  Fingerprint: (p) => <Svg {...p}><path d="M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4"/><path d="M14 13.12c0 2.38 0 6.38-1 8.88"/><path d="M17.29 21.02c.12-.6.43-2.3.5-3.02"/><path d="M2 12a10 10 0 0 1 18-6"/><path d="M2 16h.01"/><path d="M21.8 16c.2-2 .131-5.354 0-6"/><path d="M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2"/><path d="M8.65 22c.21-.66.45-1.32.57-2"/><path d="M9 6.8a6 6 0 0 1 9 5.2v2"/></Svg>,
  ChevronRight: (p) => <Svg {...p}><polyline points="9 18 15 12 9 6"/></Svg>,
};

/* ---------- copy-to-clipboard button ---------- */
function CopyButton({ text, label = 'Copy', size = 'sm', variant = 'ghost' }) {
  const [done, setDone] = React.useState(false);
  function go() {
    const t = typeof text === 'function' ? text() : text;
    navigator.clipboard.writeText(t || '').then(() => {
      setDone(true); setTimeout(() => setDone(false), 1400);
    });
  }
  return (
    <Button variant={done ? 'secondary' : variant} size={size} onClick={go}
      iconLeft={done ? <Icon.Check size={15}/> : <Icon.Copy size={15}/>}>
      {done ? 'Copied' : label}
    </Button>
  );
}

/* ---------- status pill ---------- */
const STATUS = {
  valid: { tone: 'success', label: 'Valid', dot: true },
  expiring: { tone: 'warning', label: 'Expiring soon', dot: true },
  expired: { tone: 'danger', label: 'Expired', dot: true },
  'not-yet-valid': { tone: 'warning', label: 'Not yet valid', dot: true },
};
function StatusPill({ status, size }) {
  const s = STATUS[status] || { tone: 'neutral', label: status };
  return <Badge tone={s.tone} dot={s.dot} size={size}>{s.label}</Badge>;
}

/* ---------- titled section card ---------- */
const cardLabelStyle = {
  font: 'var(--caption)', textTransform: 'uppercase', letterSpacing: 'var(--tracking-eyebrow)',
  color: 'var(--text-brand)', display: 'flex', alignItems: 'center', gap: 8, margin: 0,
};
function SectionCard({ icon, title, right, children, pad = 'md' }) {
  return (
    <Card elevation="sm" padding={pad}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 'var(--space-4)' }}>
        <p style={cardLabelStyle}>{icon}{title}</p>
        {right}
      </div>
      {children}
    </Card>
  );
}

/* ---------- definition rows ---------- */
function DefList({ rows }) {
  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'minmax(140px, 200px) 1fr', columnGap: 'var(--space-6)', rowGap: 'var(--space-3)' }}>
      {rows.filter(Boolean).map((r, i) => (
        <React.Fragment key={i}>
          <div style={{ font: 'var(--body-sm)', color: 'var(--text-muted)', fontWeight: 500 }}>{r.label}</div>
          <div style={{ font: 'var(--body-sm)', color: 'var(--text-strong)', wordBreak: r.break ? 'break-all' : 'normal', fontFamily: r.mono ? 'var(--font-mono)' : 'var(--font-sans)', fontSize: r.mono ? '13px' : undefined }}>
            {r.value || <span style={{ color: 'var(--text-subtle)' }}>—</span>}
          </div>
        </React.Fragment>
      ))}
    </div>
  );
}

/* ---------- monospace output block with copy + download ---------- */
function CodeBlock({ value, filename, downloadLabel = 'Download .pem' }) {
  function download() {
    const blob = new Blob([value], { type: 'application/x-pem-file' });
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob); a.download = filename || 'output.pem';
    document.body.appendChild(a); a.click(); a.remove();
    setTimeout(() => URL.revokeObjectURL(a.href), 2000);
  }
  return (
    <div>
      <div style={{ display: 'flex', gap: 'var(--space-2)', justifyContent: 'flex-end', marginBottom: 'var(--space-2)' }}>
        <CopyButton text={value} variant="outline" />
        {filename && <Button variant="outline" size="sm" iconLeft={<Icon.Download size={15}/>} onClick={download}>{downloadLabel}</Button>}
      </div>
      <pre style={{
        margin: 0, padding: 'var(--space-4)', background: 'var(--blue-900)', color: '#CBD8F2',
        borderRadius: 'var(--radius-md)', fontFamily: 'var(--font-mono)', fontSize: '12px',
        lineHeight: 1.55, overflowX: 'auto', whiteSpace: 'pre', maxHeight: 320, overflowY: 'auto',
      }}>{value}</pre>
    </div>
  );
}

/* ---------- notice banner ---------- */
function Notice({ tone = 'info', title, children, icon }) {
  const tones = {
    info: { bg: 'var(--blue-50)', bd: 'var(--blue-200)', fg: 'var(--brand-ink)' },
    warning: { bg: 'var(--warning-bg)', bd: 'var(--amber-500)', fg: 'var(--amber-600)' },
    danger: { bg: 'var(--danger-bg)', bd: 'var(--red-500)', fg: 'var(--red-600)' },
    success: { bg: 'var(--success-bg)', bd: 'var(--green-500)', fg: 'var(--green-600)' },
  }[tone];
  return (
    <div style={{ display: 'flex', gap: 'var(--space-3)', padding: 'var(--space-4)', background: tones.bg,
      border: '1px solid ' + tones.bd, borderRadius: 'var(--radius-md)' }}>
      <div style={{ color: tones.fg, flex: 'none', marginTop: 1 }}>{icon || <Icon.Alert size={18}/>}</div>
      <div>
        {title && <div style={{ font: 'var(--body-sm)', fontWeight: 600, color: 'var(--text-strong)', marginBottom: children ? 4 : 0 }}>{title}</div>}
        {children && <div style={{ font: 'var(--body-sm)', color: 'var(--text-body)', lineHeight: 1.55 }}>{children}</div>}
      </div>
    </div>
  );
}

/* ---------- file dropzone ---------- */
function Dropzone({ onFile, accept = '.pem,.crt,.cer,.der,.txt,.csr' }) {
  const [over, setOver] = React.useState(false);
  const inputRef = React.useRef(null);
  function handle(file) { if (file) onFile(file); }
  return (
    <div
      onDragOver={(e) => { e.preventDefault(); setOver(true); }}
      onDragLeave={() => setOver(false)}
      onDrop={(e) => { e.preventDefault(); setOver(false); handle(e.dataTransfer.files[0]); }}
      onClick={() => inputRef.current && inputRef.current.click()}
      style={{
        border: '1.5px dashed ' + (over ? 'var(--brand)' : 'var(--border-strong)'),
        background: over ? 'var(--blue-50)' : 'var(--surface-sunken)',
        borderRadius: 'var(--radius-md)', padding: 'var(--space-8) var(--space-6)', textAlign: 'center',
        cursor: 'pointer', transition: 'all var(--dur-base) var(--ease-out)',
      }}>
      <div style={{ color: over ? 'var(--brand)' : 'var(--text-muted)', display: 'flex', justifyContent: 'center', marginBottom: 'var(--space-2)' }}><Icon.Upload size={24}/></div>
      <div style={{ font: 'var(--body)', color: 'var(--text-strong)', fontWeight: 500 }}>Drop a certificate file, or click to browse</div>
      <div style={{ font: 'var(--body-sm)', color: 'var(--text-muted)', marginTop: 4 }}>.pem · .crt · .cer · .der · .csr</div>
      <input ref={inputRef} type="file" accept={accept} style={{ display: 'none' }}
        onChange={(e) => { handle(e.target.files[0]); e.target.value = ''; }} />
    </div>
  );
}

Object.assign(window, {
  Icon, Svg, CopyButton, StatusPill, SectionCard, DefList, CodeBlock, Notice, Dropzone, STATUS,
});
