import type { ElementType, FiveElementsScore, Pillar } from '@/lib/bazi/types';
import { HEAVENLY_STEMS } from '@/lib/bazi/stems';
import { CONTROLS, ELEMENT_INFO, GENERATES, PILLAR_GUIDE } from '@/lib/bazi/guide';
import { shioName } from '@/lib/bazi/shio';
import { useLocale, useMessages } from '@/i18n/client';
import { cn } from '@/lib/cn';
import { ELEMENT_ORDER, ELEMENT_STYLE } from './elements';

/** Raw colours for SVG, matching the theme tokens. */
export const ELEMENT_HEX: Record<ElementType, string> = {
  Wood: '#3FA36B',
  Fire: '#E0505B',
  Earth: '#E2A33B',
  Metal: '#9AA0B0',
  Water: '#3E7BEA',
};

type PillarKey = 'year' | 'month' | 'day' | 'hour';

/** The four pillars with pinyin, element, zodiac animal, hidden stems and what each pillar stands for. */
export function DetailedPillars({ pillars }: { pillars: Record<PillarKey, Pillar> }) {
  const locale = useLocale();
  const t = useMessages().insights;
  const el = ELEMENT_INFO[locale];
  const keys: PillarKey[] = ['year', 'month', 'day', 'hour'];
  return (
    <div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
      {keys.map((k) => {
        const p = pillars[k];
        const guide = PILLAR_GUIDE[locale][k];
        const isDay = k === 'day';
        const hidden = p.branch.hiddenStems
          .map((c) => HEAVENLY_STEMS.find((s) => s.chinese === c))
          .filter((s) => s !== undefined);
        return (
          <div
            key={k}
            className={cn('flex flex-col rounded-2xl p-4 text-center ring-1', isDay ? 'bg-accent-soft ring-accent/25' : 'bg-canvas ring-line')}
          >
            <p className="text-xs font-semibold text-ink">{guide.label}</p>
            <p className="text-[11px] text-subtle">{guide.life}</p>

            <p className="mt-3 text-[10px] font-medium tracking-wider text-subtle uppercase">{t.stem}</p>
            <p className={cn('font-serif text-[32px] leading-tight', ELEMENT_STYLE[p.stem.element].text)}>{p.stem.chinese}</p>
            <p className="text-[11px] text-ink-soft">
              {p.stem.pinyin} · {t.polarity[p.stem.polarity]} {el[p.stem.element].name}
            </p>

            <p className="mt-3 text-[10px] font-medium tracking-wider text-subtle uppercase">{t.branch}</p>
            <p className={cn('font-serif text-[32px] leading-tight', ELEMENT_STYLE[p.branch.element].text)}>{p.branch.chinese}</p>
            <p className="text-[11px] text-ink-soft">
              {p.branch.pinyin} · {el[p.branch.element].name}
            </p>
            <p className="text-[11px] text-muted">{t.shio(shioName(p.branch.chinese, locale))}</p>

            <p className="mt-3 text-[10px] font-medium tracking-wider text-subtle uppercase">{t.hidden}</p>
            <p className="mt-1 flex justify-center gap-1.5">
              {hidden.map((s) => (
                <span
                  key={s.chinese}
                  title={`${s.pinyin} · ${t.polarity[s.polarity]} ${el[s.element].name}`}
                  className={cn('font-serif text-base', ELEMENT_STYLE[s.element].text)}
                >
                  {s.chinese}
                </span>
              ))}
            </p>

            <p className="mt-3 border-t border-line pt-3 text-left text-[11px] leading-snug text-muted">
              {isDay && <span className="font-semibold text-accent">{t.dayMasterTag}</span>}
              {guide.meaning}
            </p>
          </div>
        );
      })}
    </div>
  );
}

/**
 * The generating cycle (outer ring, solid arrows) and controlling cycle (inner star, dashed)
 * with each element's node sized by its strength in the chart.
 */
export function ElementCycle({
  elements,
  dayMaster,
  className,
}: {
  elements: FiveElementsScore;
  dayMaster: ElementType;
  className?: string;
}) {
  const locale = useLocale();
  const t = useMessages().insights;
  const info = ELEMENT_INFO[locale];
  const cx = 130;
  const cy = 128;
  const R = 92;
  // Fire on top, then clockwise along the generating cycle.
  const order: ElementType[] = ['Fire', 'Earth', 'Metal', 'Water', 'Wood'];
  const pos = Object.fromEntries(
    order.map((el, i) => {
      const a = -Math.PI / 2 + (i * 2 * Math.PI) / 5;
      return [el, { x: cx + R * Math.cos(a), y: cy + R * Math.sin(a) }];
    }),
  ) as Record<ElementType, { x: number; y: number }>;
  const nodeR = (el: ElementType) => 14 + (elements[el] / 100) * 16;

  /** Line from a to b, trimmed so it starts/ends at the node edges. */
  const edge = (a: ElementType, b: ElementType) => {
    const p = pos[a];
    const q = pos[b];
    const d = Math.hypot(q.x - p.x, q.y - p.y);
    const ux = (q.x - p.x) / d;
    const uy = (q.y - p.y) / d;
    const s = nodeR(a) + 3;
    const e = nodeR(b) + 6;
    return { x1: p.x + ux * s, y1: p.y + uy * s, x2: q.x - ux * e, y2: q.y - uy * e };
  };

  return (
    <svg viewBox="0 0 260 260" className={className} role="img" aria-label={t.elementCycle}>
      <defs>
        <marker id="gen-arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto">
          <path d="M0 0 L10 5 L0 10 z" fill="#9AA0B0" />
        </marker>
        <marker id="ctl-arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="5" markerHeight="5" orient="auto">
          <path d="M0 0 L10 5 L0 10 z" fill="#E0505B" fillOpacity="0.55" />
        </marker>
      </defs>

      {ELEMENT_ORDER.map((el) => {
        const g = edge(el, GENERATES[el]);
        const c = edge(el, CONTROLS[el]);
        return (
          <g key={el}>
            <line {...g} stroke="#9AA0B0" strokeWidth="1.5" markerEnd="url(#gen-arrow)" />
            <line {...c} stroke="#E0505B" strokeOpacity="0.45" strokeWidth="1" strokeDasharray="3 3" markerEnd="url(#ctl-arrow)" />
          </g>
        );
      })}

      {ELEMENT_ORDER.map((el) => {
        const { x, y } = pos[el];
        const r = nodeR(el);
        return (
          <g key={el}>
            {el === dayMaster && <circle cx={x} cy={y} r={r + 5} fill="none" stroke={ELEMENT_HEX[el]} strokeWidth="2" strokeDasharray="2 3" />}
            <circle cx={x} cy={y} r={r} fill={ELEMENT_HEX[el]} fillOpacity="0.9" />
            <text x={x} y={y - 1} textAnchor="middle" dominantBaseline="middle" className="fill-white font-serif text-[15px]">
              {info[el].symbol}
            </text>
            <text x={x} y={y + 11} textAnchor="middle" className="fill-white text-[8px] font-semibold">
              {elements[el]}
            </text>
            <text x={x} y={y + r + 12} textAnchor="middle" className="fill-ink-soft text-[10px] font-medium">
              {info[el].name}
            </text>
          </g>
        );
      })}
    </svg>
  );
}
