import { ImageResponse } from 'next/og';
import { getRegisters } from '@/services/register.service';

export const runtime = 'nodejs';

export const size = {
  width: 1200,
  height: 630,
};

export const contentType = 'image/png';

const buildRegisterSummaryLines = (register: { description: string; text: string; modes: { text: string }[] }) => {
  const isInfoLine = (line: string) =>
    line.length > 0 &&
    !line.startsWith('//') &&
    !line.startsWith('(R') &&
    !line.startsWith('(W') &&
    !line.startsWith('(R/W') &&
    !line.startsWith('*') &&
    !/^bits?\s+\d/i.test(line);

  const normalizeLines = (raw: string) => {
    const lines: string[] = [];
    const rawLines = raw.split('\n');
    for (const rawLine of rawLines) {
      const trimmed = rawLine.trim();
      if (!trimmed) {
        if (lines.length > 0 && lines[lines.length - 1] !== '') {
          lines.push('');
        }
        continue;
      }
      if (isInfoLine(trimmed)) {
        lines.push(trimmed);
      }
    }
    return lines;
  };

  const textLines = normalizeLines(register.text);
  const modeLines = register.modes.flatMap(mode => normalizeLines(mode.text));
  const descriptionLines = normalizeLines(register.description);

  const combined: string[] = [];
  const appendBlock = (block: string[]) => {
    if (block.length === 0) return;
    if (combined.length > 0 && combined[combined.length - 1] !== '') {
      combined.push('');
    }
    combined.push(...block);
  };

  appendBlock(textLines);
  appendBlock(modeLines);
  appendBlock(descriptionLines);

  const deduped: string[] = [];
  const seen = new Set<string>();
  for (const line of combined) {
    if (!line) {
      if (deduped.length > 0 && deduped[deduped.length - 1] !== '') {
        deduped.push('');
      }
      continue;
    }
    if (seen.has(line)) {
      continue;
    }
    seen.add(line);
    deduped.push(line);
  }

  return deduped.length > 0 ? deduped : ['Spectrum Next register details and bit-level behavior.'];
};

const splitLongWord = (word: string, maxLineLength: number) => {
  if (word.length <= maxLineLength) return [word];
  const chunks: string[] = [];
  for (let idx = 0; idx < word.length; idx += maxLineLength - 1) {
    chunks.push(`${word.slice(idx, idx + maxLineLength - 1)}-`);
  }
  const last = chunks[chunks.length - 1];
  chunks[chunks.length - 1] = last.endsWith('-') ? last.slice(0, -1) : last;
  return chunks;
};

const wrapText = (text: string, maxLineLength: number) => {
  const words = text
    .split(/\s+/)
    .filter(Boolean)
    .flatMap(word => splitLongWord(word, maxLineLength));
  const lines: string[] = [];
  let current = '';

  for (const word of words) {
    const next = current ? `${current} ${word}` : word;
    if (next.length > maxLineLength && current) {
      lines.push(current);
      current = word;
    } else {
      current = next;
    }
  }

  if (current) {
    lines.push(current);
  }

  return lines;
};

const wrapTextLines = (sourceLines: string[], maxLineLength: number, maxLines: number) => {
  const output: string[] = [];
  for (const line of sourceLines) {
    if (output.length >= maxLines) break;
    if (!line) {
      if (output.length > 0 && output[output.length - 1] !== '') {
        output.push('');
      }
      continue;
    }
    const wrapped = wrapText(line, maxLineLength);
    for (const wrappedLine of wrapped) {
      if (output.length >= maxLines) break;
      output.push(wrappedLine);
    }
  }
  return output.slice(0, maxLines);
};

export default async function Image({ params }: { params: Promise<{ hex: string }> }) {
  const { hex } = await params;
  const targetHex = decodeURIComponent(hex).toLowerCase();
  const registers = await getRegisters();
  const register = registers.find(r => r.hex_address.toLowerCase() === targetHex);

  const title = register ? `${register.hex_address} ${register.name}` : 'Spectrum Next Register';
  const summaryLinesSource = register
    ? buildRegisterSummaryLines(register)
    : ['Register details not found.'];
  const decAddress = register ? `Dec ${register.dec_address}` : '';
  const titleLines = wrapTextLines([title], 32, 2);
  const summaryLines = wrapTextLines(summaryLinesSource, 54, 6);

  return new ImageResponse(
    (
      <div
        style={{
          width: '1200px',
          height: '630px',
          display: 'flex',
          background: 'linear-gradient(135deg, #3f1f6e 0%, #593196 55%, #7a4cc4 100%)',
          color: '#f3f2ed',
          fontFamily: 'Arial, sans-serif',
          padding: '64px',
          boxSizing: 'border-box',
        }}
      >
        <div style={{ display: 'flex', flexDirection: 'column', gap: '24px', width: '100%' }}>
          <div style={{ fontSize: '28px', letterSpacing: '2px', textTransform: 'uppercase', color: '#e8dcff' }}>
            Spectrum Next Explorer
          </div>
          <div
            style={{
              display: 'flex',
              flexDirection: 'column',
              gap: '6px',
              fontSize: '68px',
              fontWeight: 700,
              lineHeight: 1.05,
            }}
          >
            {titleLines.map(line => (
              <div key={line}>{line}</div>
            ))}
          </div>
          <div
            style={{
              display: 'flex',
              flexDirection: 'column',
              gap: '6px',
              fontSize: '32px',
              lineHeight: 1.35,
              color: '#f7f1ff',
            }}
          >
            {summaryLines.map(line => (
              <div key={line}>{line}</div>
            ))}
          </div>
          <div style={{ marginTop: 'auto', fontSize: '26px', color: '#dacbff' }}>
            {decAddress}
          </div>
        </div>
      </div>
    ),
    {
      width: size.width,
      height: size.height,
    }
  );
}
