import { useMemo } from 'react';

import { cn } from '@/lib/utils';
import { getColors } from '@/lib/colorMomentUtils';
import type { NostrEvent } from '@nostrify/nostrify';

type Layout = 'horizontal' | 'vertical' | 'grid' | 'star' | 'checkerboard' | 'diagonalStripes';

function getTag(tags: string[][], name: string): string | undefined {
  return tags.find(([n]) => n === name)?.[1];
}



/** Compute a best-fit grid: cols × rows for n items. */
function gridDimensions(n: number): { cols: number; rows: number } {
  if (n <= 3) return { cols: n, rows: 1 };
  if (n === 4) return { cols: 2, rows: 2 };
  if (n === 5) return { cols: 3, rows: 2 };
  return { cols: 3, rows: 2 };
}

/** Relative luminance of a hex color (0-1). */
function luminance(hex: string): number {
  const r = parseInt(hex.slice(1, 3), 16) / 255;
  const g = parseInt(hex.slice(3, 5), 16) / 255;
  const b = parseInt(hex.slice(5, 7), 16) / 255;
  const toLinear = (c: number) => (c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4);
  return 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);
}

// ─── Layout renderers ──────────────────────────────────────

function HorizontalLayout({ colors }: { colors: string[] }) {
  return (
    <div className="flex flex-col w-full rounded-2xl overflow-hidden" style={{ height: 180 }}>
      {colors.map((color, i) => (
        <div key={i} className="flex-1" style={{ backgroundColor: color }} />
      ))}
    </div>
  );
}

function VerticalLayout({ colors }: { colors: string[] }) {
  return (
    <div className="flex w-full rounded-2xl overflow-hidden" style={{ height: 180 }}>
      {colors.map((color, i) => (
        <div key={i} className="flex-1" style={{ backgroundColor: color }} />
      ))}
    </div>
  );
}

function GridLayout({ colors }: { colors: string[] }) {
  const { cols } = gridDimensions(colors.length);
  return (
    <div
      className="grid w-full rounded-2xl overflow-hidden"
      style={{
        height: 180,
        gridTemplateColumns: `repeat(${cols}, 1fr)`,
      }}
    >
      {colors.map((color, i) => (
        <div key={i} style={{ backgroundColor: color }} />
      ))}
    </div>
  );
}

/** Build a clip-path polygon for a pie slice with slight overlap to prevent gaps. */
function pieSliceClipPath(index: number, total: number): string {
  const angle = 360 / total;
  const overlap = 0.5;
  const startAngle = index * angle - 90 - overlap;
  const sweepAngle = angle + overlap * 2;
  const scale = 1.5; // extend past edges so slices cover the full rect
  const steps = 12;

  const points: string[] = ['50% 50%'];
  for (let i = 0; i <= steps; i++) {
    const a = startAngle + (sweepAngle * i) / steps;
    const rad = (a * Math.PI) / 180;
    const x = 50 + 50 * scale * Math.cos(rad);
    const y = 50 + 50 * scale * Math.sin(rad);
    points.push(`${x}% ${y}%`);
  }
  return `polygon(${points.join(', ')})`;
}

function StarLayout({ colors }: { colors: string[] }) {
  return (
    <div className="relative w-full rounded-2xl overflow-hidden" style={{ height: 180 }}>
      {/* Background fill to cover the center seam where all slices meet */}
      <div className="absolute inset-0" style={{ backgroundColor: colors[0] }} />
      {colors.map((color, i) => (
        <div
          key={i}
          className="absolute inset-0"
          style={{
            backgroundColor: color,
            clipPath: pieSliceClipPath(i, colors.length),
          }}
        />
      ))}
    </div>
  );
}

function CheckerboardLayout({ colors }: { colors: string[] }) {
  const n = colors.length;
  const height = 180;
  // Target ~6 rows so squares are large and legible
  const rows = n * Math.max(2, 4 - n);
  const cellSize = height / rows;
  // Enough columns to cover any container width (overflow is clipped)
  const cols = Math.ceil(600 / cellSize);

  const cells: { color: string; key: string }[] = [];
  for (let row = 0; row < rows; row++) {
    for (let col = 0; col < cols; col++) {
      const colorIndex = (row + col) % n;
      cells.push({ color: colors[colorIndex], key: `${row}-${col}` });
    }
  }

  return (
    <div
      className="w-full rounded-2xl overflow-hidden"
      style={{ height }}
    >
      <div
        style={{
          display: 'grid',
          gridTemplateColumns: `repeat(${cols}, ${cellSize}px)`,
          gridTemplateRows: `repeat(${rows}, ${cellSize}px)`,
        }}
      >
        {cells.map(({ color, key }) => (
          <div key={key} style={{ backgroundColor: color }} />
        ))}
      </div>
    </div>
  );
}

function DiagonalStripesLayout({ colors }: { colors: string[] }) {
  const n = colors.length;
  const H = 180;
  // Use a canvas wider than the visible area by H so that parallelogram stripes
  // at a 45° diagonal fill the rectangle exactly. The viewBox is (W+H) × H but
  // we clip it back to W × H via the wrapper div + overflow-hidden.
  // Each stripe is a true parallelogram with vertical width W/n and a horizontal
  // shift of H from top to bottom, giving a consistent 45° diagonal boundary.
  const W = 400;
  const totalW = W + H; // canvas wide enough so last stripe reaches bottom-right
  const stripeW = totalW / n;

  return (
    <div className="w-full rounded-2xl overflow-hidden" style={{ height: H }}>
      <svg
        width="100%"
        height="100%"
        viewBox={`0 0 ${W} ${H}`}
        preserveAspectRatio="none"
        xmlns="http://www.w3.org/2000/svg"
        shapeRendering="geometricPrecision"
      >
        {colors.map((color, i) => {
          // Stripe i: parallelogram where the top edge is at x=[i*sw, (i+1)*sw]
          // and the bottom edge shifts left by H (height), giving a 45° angle.
          const tx0 = i * stripeW;             // top-left x
          const tx1 = (i + 1) * stripeW;     // top-right x
          const bx0 = i * stripeW - H;       // bottom-left x (shifted left by H)
          const bx1 = (i + 1) * stripeW - H; // bottom-right x
          const points = [
            `${tx0},0`,
            `${tx1},0`,
            `${bx1},${H}`,
            `${bx0},${H}`,
          ].join(' ');
          return <polygon key={i} points={points} fill={color} />;
        })}
      </svg>
    </div>
  );
}

// ─── Main component ──────────────────────────────────────

const LAYOUT_MAP: Record<Layout, React.FC<{ colors: string[] }>> = {
  horizontal: HorizontalLayout,
  vertical: VerticalLayout,
  grid: GridLayout,
  star: StarLayout,
  checkerboard: CheckerboardLayout,
  diagonalStripes: DiagonalStripesLayout,
};

/** Standalone blinking eye button — REMOVED.
 *
 * This component used to let any user apply an arbitrary kind-3367 event's
 * palette as their active theme via `applyCustomTheme(paletteToTheme(...))`.
 * Agora no longer supports user-customizable themes, so the apply path has
 * been removed entirely. Color Moments still render as palette art via
 * `ColorMomentContent` below.
 */

export function ColorMomentContent({ event }: { event: NostrEvent }) {
  const colors = useMemo(() => getColors(event.tags), [event.tags]);
  const layout = (getTag(event.tags, 'layout') ?? 'horizontal') as Layout;
  const name = getTag(event.tags, 'name');
  const rawContent = event.content.trim();
  // Only treat content as an emoji if it's a single grapheme cluster (emoji or short symbol).
  // Long text should not be overlaid on the palette.
  const isSingleEmoji = rawContent.length > 0 && [...rawContent].length <= 2 && /\p{Emoji}/u.test(rawContent);
  const emoji = isSingleEmoji ? rawContent : undefined;

  const LayoutComponent = LAYOUT_MAP[layout] ?? HorizontalLayout;

  // Determine whether overlay text should be light or dark
  const avgLum = useMemo(() => {
    if (colors.length === 0) return 0.5;
    return colors.reduce((sum, c) => sum + luminance(c), 0) / colors.length;
  }, [colors]);
  const overlayTextClass = avgLum > 0.5 ? 'text-black/80' : 'text-white/90';

  if (colors.length === 0) return null;

  return (
    <div className="mt-2">
      {/* Name above the palette */}
      {name && (
        <p className="text-[15px] font-medium mb-2">{name}</p>
      )}

      {/* Color palette with emoji overlay */}
      <div className="relative isolate">
        <LayoutComponent colors={colors} />

        {/* Emoji centered over the palette */}
        {emoji && (
          <div className="absolute inset-0 flex items-center justify-center pointer-events-none">
            <span
              className={cn(
                'text-4xl drop-shadow-lg select-none',
                overlayTextClass,
              )}
            >
              {emoji}
            </span>
          </div>
        )}
      </div>

      {/* Color hex swatches */}
      <div className="flex flex-wrap items-center gap-1.5 mt-2">
        {colors.map((color, i) => (
          <button
            key={i}
            onClick={(e) => {
              e.stopPropagation();
              navigator.clipboard.writeText(color);
            }}
            className="flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] font-mono text-muted-foreground hover:bg-secondary/60 transition-colors"
            title={`Copy ${color}`}
          >
            <span
              className="size-2.5 rounded-sm shrink-0 border border-border/40"
              style={{ backgroundColor: color }}
            />
            {color}
          </button>
        ))}
      </div>
    </div>
  );
}
