import * as React from 'react';

// Fourteen-segment geometry in a local 10 x 18 digit cell.
// Outer ring: a top, b top-right, c bottom-right, d bottom, e bottom-left,
// f top-left. Middle bar: g1 left, g2 right. Center verticals: i top, l
// bottom. Diagonals: h TL, j TR, k BL, m BR.

const W = 10;
const H = 18;
const GAP = 3.4;
const HALF = 1.05;
const INSET = 0.45;

const hSeg = (y: number, x1: number, x2: number): string => {
  const a = x1 + INSET;
  const b = x2 - INSET;
  return `${a},${y} ${a + HALF},${y - HALF} ${b - HALF},${y - HALF} ${b},${y} ${b - HALF},${y + HALF} ${a + HALF},${y + HALF}`;
};

const vSeg = (x: number, y1: number, y2: number): string => {
  const a = y1 + INSET;
  const b = y2 - INSET;
  return `${x},${a} ${x + HALF},${a + HALF} ${x + HALF},${b - HALF} ${x},${b} ${x - HALF},${b - HALF} ${x - HALF},${a + HALF}`;
};

type Seg14 =
  | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
  | 'g1' | 'g2' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm';

const POLY: Partial<Record<Seg14, string>> = {
  a: hSeg(1, 1, 9),
  d: hSeg(17, 1, 9),
  g1: hSeg(9, 1, 5),
  g2: hSeg(9, 5, 9),
  f: vSeg(1, 1, 9),
  b: vSeg(9, 1, 9),
  e: vSeg(1, 9, 17),
  c: vSeg(9, 9, 17),
  i: vSeg(5, 1, 9),
  l: vSeg(5, 9, 17),
};

/** Diagonals render as thick lines: [x1, y1, x2, y2]. */
const DIAG: Partial<Record<Seg14, [number, number, number, number]>> = {
  h: [2.2, 2.7, 4.1, 7.2],
  j: [7.8, 2.7, 5.9, 7.2],
  k: [4.1, 10.8, 2.2, 15.3],
  m: [5.9, 10.8, 7.8, 15.3],
};

const CHARS: Record<string, Seg14[]> = {
  '0': ['a', 'b', 'c', 'd', 'e', 'f'],
  '1': ['b', 'c'],
  '2': ['a', 'b', 'g1', 'g2', 'e', 'd'],
  '3': ['a', 'b', 'c', 'd', 'g1', 'g2'],
  '4': ['f', 'g1', 'g2', 'b', 'c'],
  '5': ['a', 'f', 'g1', 'g2', 'c', 'd'],
  '6': ['a', 'f', 'g1', 'g2', 'e', 'c', 'd'],
  '7': ['a', 'b', 'c'],
  '8': ['a', 'b', 'c', 'd', 'e', 'f', 'g1', 'g2'],
  '9': ['a', 'b', 'c', 'd', 'f', 'g1', 'g2'],
  A: ['a', 'b', 'c', 'e', 'f', 'g1', 'g2'],
  B: ['a', 'b', 'c', 'd', 'i', 'l', 'g2'],
  C: ['a', 'd', 'e', 'f'],
  D: ['a', 'b', 'c', 'd', 'i', 'l'],
  E: ['a', 'd', 'e', 'f', 'g1', 'g2'],
  F: ['a', 'e', 'f', 'g1', 'g2'],
  G: ['a', 'c', 'd', 'e', 'f', 'g2'],
  H: ['b', 'c', 'e', 'f', 'g1', 'g2'],
  I: ['a', 'd', 'i', 'l'],
  J: ['b', 'c', 'd', 'e'],
  K: ['e', 'f', 'g1', 'j', 'm'],
  L: ['d', 'e', 'f'],
  M: ['b', 'c', 'e', 'f', 'h', 'j'],
  N: ['b', 'c', 'e', 'f', 'h', 'm'],
  O: ['a', 'b', 'c', 'd', 'e', 'f'],
  P: ['a', 'b', 'e', 'f', 'g1', 'g2'],
  Q: ['a', 'b', 'c', 'd', 'e', 'f', 'm'],
  R: ['a', 'b', 'e', 'f', 'g1', 'g2', 'm'],
  S: ['a', 'c', 'd', 'f', 'g1', 'g2'],
  T: ['a', 'i', 'l'],
  U: ['b', 'c', 'd', 'e', 'f'],
  V: ['e', 'f', 'j', 'k'],
  W: ['b', 'c', 'e', 'f', 'k', 'm'],
  X: ['h', 'j', 'k', 'm'],
  Y: ['h', 'j', 'l'],
  Z: ['a', 'd', 'j', 'k'],
  '-': ['g1', 'g2'],
  '_': ['d'],
  '=': ['g1', 'g2', 'd'],
  '+': ['g1', 'g2', 'i', 'l'],
  '*': ['g1', 'g2', 'h', 'i', 'j', 'k', 'l', 'm'],
  '/': ['j', 'k'],
  '\\': ['h', 'm'],
  '?': ['a', 'b', 'g2', 'l'],
  ' ': [],
};

const ALL_SEGMENTS = Object.keys({ ...POLY, ...DIAG }) as Seg14[];

export interface AlphaDisplayProps {
  /** Text: A–Z, 0–9, space, - _ = + * / \ ? and '.' (attaches to the previous cell). */
  value: string;
  /** Fixed number of character cells; the text is padded/cropped to fit. */
  chars?: number;
  align?: 'left' | 'right';
  /** Character height in px. Default: 22. */
  height?: number;
  color?: string;
  /** Panel background. Set to 'none' to disable. */
  background?: string;
  /** Opacity of unlit segments. Default: 0.08. */
  ghostOpacity?: number;
  /** Italic skew in degrees. Default: 6. */
  skew?: number;
  /** LED glow strength (0 disables). Default: 1.4. */
  glow?: number;
  padding?: number;
  className?: string;
  style?: React.CSSProperties;
}

/**
 * Fourteen-segment alphanumeric LED display — preset names, modes, messages.
 * The alphanumeric sibling of `SegmentDisplay`.
 */
export const AlphaDisplay: React.FC<AlphaDisplayProps> = ({
  value,
  chars,
  align = 'left',
  height = 22,
  color = '#ffb84d',
  background = '#0a0d0c',
  ghostOpacity = 0.08,
  skew = 6,
  glow = 1.4,
  padding = 6,
  className,
  style,
}) => {
  const filterId = React.useId();

  let text = value.toUpperCase();
  if (chars !== undefined) {
    const cellCount = text.replace(/\./g, '').length;
    if (cellCount < chars) {
      const pad = ' '.repeat(chars - cellCount);
      text = align === 'right' ? pad + text : text + pad;
    } else if (cellCount > chars) {
      let kept = 0;
      let out = '';
      for (const ch of text) {
        if (ch !== '.' && kept === chars) break;
        if (ch !== '.') kept++;
        out += ch;
      }
      text = out;
    }
  }

  const cells: React.ReactNode[] = [];
  let x = 0;
  let key = 0;
  for (const ch of text) {
    if (ch === '.') {
      cells.push(
        <circle key={key++} cx={x - GAP / 2 + 0.2} cy={H - 1.2} r={1.15} fill={color} />,
      );
      continue;
    }
    const lit = new Set(CHARS[ch] ?? []);
    const parts: React.ReactNode[] = [];
    for (const seg of ALL_SEGMENTS) {
      const on = lit.has(seg);
      if (!on && ghostOpacity <= 0) continue;
      const opacity = on ? 1 : ghostOpacity;
      const poly = POLY[seg];
      if (poly) {
        parts.push(<polygon key={seg} points={poly} fill={color} opacity={opacity} />);
      } else {
        const [x1, y1, x2, y2] = DIAG[seg]!;
        parts.push(
          <line
            key={seg}
            x1={x1}
            y1={y1}
            x2={x2}
            y2={y2}
            stroke={color}
            strokeWidth={1.5}
            strokeLinecap="butt"
            opacity={opacity}
          />,
        );
      }
    }
    cells.push(
      <g key={key++} transform={`translate(${x} 0)`}>
        {parts}
      </g>,
    );
    x += W + GAP;
  }

  const contentW = Math.max(x - GAP, 0);
  const scale = height / H;
  const w = contentW * scale + padding * 2 + height * 0.15;
  const h = height + padding * 2;

  return (
    <svg
      width={w}
      height={h}
      viewBox={`0 0 ${w} ${h}`}
      className={className}
      style={style}
      role="img"
      aria-label={value}
    >
      {glow > 0 && (
        <defs>
          <filter id={filterId} x="-40%" y="-40%" width="180%" height="180%">
            <feGaussianBlur stdDeviation={glow} result="blur" />
            <feMerge>
              <feMergeNode in="blur" />
              <feMergeNode in="SourceGraphic" />
            </feMerge>
          </filter>
        </defs>
      )}
      {background !== 'none' && <rect x={0} y={0} width={w} height={h} rx={4} fill={background} />}
      <g
        transform={`translate(${padding + height * 0.12} ${padding}) scale(${scale})`}
        filter={glow > 0 ? `url(#${filterId})` : undefined}
      >
        {skew ? <g transform={`skewX(${-Math.abs(skew)})`}>{cells}</g> : cells}
      </g>
    </svg>
  );
};
