// Terminal renderer for DevForgeAI installer design language.
// Variant: 'color' | 'mono' (NO_COLOR) | 'ascii' (TERM=dumb).
// All color tokens degrade automatically; symbol glyphs swap on 'ascii'.

const VariantCtx = React.createContext({ variant: 'color' });

const termStyles = {
  shell: {
    background: '#0b0b0c',
    border: '1px solid #1f1f22',
    borderRadius: 10,
    overflow: 'hidden',
    fontFamily: '"JetBrains Mono", "SF Mono", Menlo, Consolas, monospace',
    fontSize: 13,
    lineHeight: '1.45',
    color: '#d4d4d8',
    boxShadow: '0 18px 40px rgba(0,0,0,.35), 0 1px 0 rgba(255,255,255,.04) inset',
    width: '100%',
    height: '100%',
    display: 'flex',
    flexDirection: 'column',
  },
  chrome: {
    height: 28,
    background: 'linear-gradient(#1a1a1d, #131316)',
    borderBottom: '1px solid #1f1f22',
    display: 'flex',
    alignItems: 'center',
    padding: '0 12px',
    gap: 6,
    flexShrink: 0,
  },
  dot: (c) => ({ width: 11, height: 11, borderRadius: '50%', background: c }),
  title: {
    flex: 1,
    textAlign: 'center',
    fontSize: 11,
    color: '#71717a',
    letterSpacing: 0.2,
    paddingRight: 36,
  },
  body: {
    padding: '14px 18px 16px',
    whiteSpace: 'pre',
    flex: 1,
    overflow: 'hidden',
  },
};

function Term({ variant = 'color', title = 'bash', children, padTop = false, wrap = false }) {
  return (
    <VariantCtx.Provider value={{ variant }}>
      <div className={`term term-${variant}`} style={termStyles.shell}>
        <div style={termStyles.chrome}>
          <span style={termStyles.dot('#ff5f56')}></span>
          <span style={termStyles.dot('#ffbd2e')}></span>
          <span style={termStyles.dot('#27c93f')}></span>
          <span style={termStyles.title}>{title}</span>
        </div>
        <div style={{ ...termStyles.body, paddingTop: padTop ? 22 : 14, whiteSpace: wrap ? 'pre-wrap' : 'pre', wordBreak: wrap ? 'break-all' : 'normal' }}>
          {children}
        </div>
      </div>
    </VariantCtx.Provider>
  );
}

// A single visible line. Children may be strings, color components,
// or other inline fragments. Whitespace is preserved.
function L({ children }) {
  return <div className="t-line">{children || '\u00a0'}</div>;
}

// Blank vertical line.
function Blank() {
  return <div className="t-line">&nbsp;</div>;
}

// Color tokens — render colored when variant === 'color', else default.
function Tone({ color, bold, dim, children }) {
  const { variant } = React.useContext(VariantCtx);
  const isColor = variant === 'color';
  const style = {
    color: isColor ? color : 'inherit',
    fontWeight: bold ? 600 : 'inherit',
    opacity: dim ? 0.58 : 1,
  };
  return <span style={style}>{children}</span>;
}

const G  = (p) => <Tone color="#4ade80" {...p} />;          // green / success
const Y  = (p) => <Tone color="#facc15" {...p} />;          // yellow / warn
const R  = (p) => <Tone color="#f87171" {...p} />;          // red / error
const Cy = (p) => <Tone color="#67e8f9" {...p} />;          // cyan / brand
const Gr = (p) => <Tone color="#9ca3af" {...p} />;          // gray / meta
const M  = (p) => <Tone color="#e879f9" {...p} />;          // magenta / accent
const B  = (p) => <Tone color="#fafafa" bold {...p} />;     // bold white
const Dm = (p) => <Tone color="#71717a" dim {...p} />;      // dim
const Wh = (p) => <Tone color="#fafafa" {...p} />;          // bold-ish white

// Bold + hue helpers (chalk composition).
const Cyb = (p) => <Tone color="#67e8f9" bold {...p} />;
const Yb  = (p) => <Tone color="#facc15" bold {...p} />;
const Gb  = (p) => <Tone color="#4ade80" bold {...p} />;
const Rb  = (p) => <Tone color="#f87171" bold {...p} />;
const Mb  = (p) => <Tone color="#e879f9" bold {...p} />;

// Symbols — Unicode in color/mono; ASCII in 'ascii' variant.
const symMap = {
  success:   { uni: '✓',  ascii: '[OK]' },
  warning:   { uni: '⚠',  ascii: '[WARN]' },
  error:     { uni: '✗',  ascii: '[ERROR]' },
  question:  { uni: '?',  ascii: '[?]' },
  info:      { uni: '›',  ascii: '--' },
  check_on:  { uni: '◉',  ascii: '[x]' },
  check_off: { uni: '◯',  ascii: '[ ]' },
  cursor:    { uni: '❯',  ascii: '>' },
  skipped:   { uni: '–',  ascii: '[SKIP]' },
  cancelled: { uni: '–',  ascii: '[CANC]' },
  dash:      { uni: '—',  ascii: '--' },
};

function Sym({ n }) {
  const { variant } = React.useContext(VariantCtx);
  const v = symMap[n];
  if (!v) return null;
  return <>{variant === 'ascii' ? v.ascii : v.uni}</>;
}

const Dash = () => <Sym n="dash" />;

// Ora-style braille spinner. ASCII variant falls back to - \ | /.
function Spinner() {
  const { variant } = React.useContext(VariantCtx);
  const frames = variant === 'ascii'
    ? ['-', '\\', '|', '/']
    : ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
  const [i, setI] = React.useState(0);
  React.useEffect(() => {
    const id = setInterval(() => setI((x) => (x + 1) % frames.length), 80);
    return () => clearInterval(id);
  }, [frames.length]);
  return <span>{frames[i]}</span>;
}

// Blinking caret for active input prompts.
function Caret() {
  const [on, setOn] = React.useState(true);
  React.useEffect(() => {
    const id = setInterval(() => setOn((x) => !x), 530);
    return () => clearInterval(id);
  }, []);
  return (
    <span style={{
      display: 'inline-block',
      width: '0.55em',
      background: on ? '#d4d4d8' : 'transparent',
      color: 'transparent',
    }}>x</span>
  );
}

// Progress bar (static at given pct, blocks ▓░).
function Bar({ pct = 50, width = 24 }) {
  const filled = Math.round((pct / 100) * width);
  const empty = width - filled;
  return (
    <>
      <Gr>[</Gr>
      <G>{'█'.repeat(filled)}</G>
      <Dm>{'░'.repeat(empty)}</Dm>
      <Gr>]</Gr>
    </>
  );
}

// Banner — pulled from src/cli/lib/banner.js verbatim (bold white).
function Banner() {
  const art = [
    '    ____             ______                         ___   ____',
    '   / __ \\  ___ _  __/ ____/___  _________ ____    /   |  /  /',
    '  / / / / / _ \\ | / / /_  / __ \\/ ___/ __ `/ _ \\ / /| | /  /  ',
    ' / /_/ / /  __/ V / __/ / /_/ / /  / /_/ /  __// ___  |/  /   ',
    '/_____/  \\___/\\_/ /_/    \\____/_/   \\__, /\\___/ //  |_/__/   ',
    '                                   /____/                     ',
  ];
  return (
    <>
      {art.map((row, i) => (
        <L key={i}><Wh bold>{row}</Wh></L>
      ))}
    </>
  );
}

// Footer step pill.
function Footer({ step, total = 9, label }) {
  return (
    <L>
      <Gr>[Step {step}/{total} </Gr><Gr><Dash /></Gr><Gr> {label}]</Gr>
    </L>
  );
}

// Make everything available globally so screens.jsx and app.jsx can use it.
Object.assign(window, {
  Term, L, Blank, Tone,
  G, Y, R, Cy, Gr, M, B, Dm, Wh,
  Cyb, Yb, Gb, Rb, Mb,
  Sym, Dash, Spinner, Caret, Bar,
  Banner, Footer,
});
