'use client';

import { memo, type ReactNode } from 'react';
import type { FdiToothId } from '@/types/treatment';
import type { ToothShapeKind } from '@/components/treatment/fdiToothMeta';
import type { FdiChartDesignId } from '@/components/ui/treatment/fdiChartDesigns';
import { getToothGlyphPaint } from '@/components/ui/treatment/toothGlyphPaint';
import type { ToothGlyphPaint } from '@/components/ui/treatment/toothGlyphPaint';
import { getToothPathModel, type ToothPathModel } from '@/components/ui/treatment/toothPathModel';
import { getTextbookToothPathModel } from '@/components/ui/treatment/toothPathModelTextbook';
import { wireframeInnerScale, wireframeOriginY } from '@/components/ui/treatment/toothGlyphStructural';

interface ToothGlyphProps {
  fdi: FdiToothId;
  kind: ToothShapeKind;
  gradientId: string;
  selected: boolean;
  upper?: boolean;
  mirrored?: boolean;
  upsideDown?: boolean;
  className?: string;
  variant?: FdiChartDesignId;
}

function filledSilhouette(
  model: ToothPathModel,
  crownFill: string,
  rootFill: string,
  stroke: string,
  strokeW: number,
): ReactNode {
  return (
    <>
      <path d={model.crown} fill={crownFill} stroke={stroke} strokeWidth={strokeW} strokeLinejoin="round" />
      {model.roots.map((d, i) => (
        <path key={i} d={d} fill={rootFill} stroke={stroke} strokeWidth={strokeW} strokeLinejoin="round" />
      ))}
    </>
  );
}

function detailOnly(model: ToothPathModel, stroke: string, strokeW: number): ReactNode {
  if (!model.detailStroke) return null;
  const { d, widthScale } = model.detailStroke;
  return <path d={d} fill="none" stroke={stroke} strokeWidth={strokeW * widthScale} strokeLinecap="round" />;
}

function renderClinicalFill(model: ToothPathModel, paint: ToothGlyphPaint): ReactNode {
  const { crownFill, rootFill, stroke, strokeW } = paint;
  return (
    <>
      {filledSilhouette(model, crownFill, rootFill, stroke, strokeW)}
      {detailOnly(model, stroke, strokeW)}
    </>
  );
}

function renderWireframe(model: ToothPathModel, paint: ToothGlyphPaint, kind: ToothShapeKind): ReactNode {
  const { stroke, strokeW } = paint;
  const outer = paint.wireOuter ?? '#f8fafc';
  const innerCol = paint.wireInner ?? '#64748b';
  const s = wireframeInnerScale(kind);
  const crownOy = wireframeOriginY('crown', kind);
  const rootOy = wireframeOriginY('root', kind);
  const rootScale = (i: number) => s - (model.roots.length > 1 ? i * 0.018 : 0);

  return (
    <>
      <g>
        <path d={model.crown} fill="none" stroke={outer} strokeWidth={strokeW + 2.2} strokeLinejoin="round" />
        <path d={model.crown} fill="none" stroke={stroke} strokeWidth={strokeW} strokeLinejoin="round" />
        <g transform={`translate(18 ${crownOy}) scale(${s}) translate(-18 ${-crownOy})`}>
          <path d={model.crown} fill="none" stroke={innerCol} strokeWidth="0.6" strokeLinejoin="round" opacity={0.7} />
        </g>
      </g>
      {model.roots.map((d, i) => (
        <g key={i}>
          <path d={d} fill="none" stroke={outer} strokeWidth={strokeW + 2.2} strokeLinejoin="round" />
          <path d={d} fill="none" stroke={stroke} strokeWidth={strokeW} strokeLinejoin="round" />
          <g transform={`translate(18 ${rootOy}) scale(${rootScale(i)}) translate(-18 ${-rootOy})`}>
            <path d={d} fill="none" stroke={innerCol} strokeWidth="0.6" strokeLinejoin="round" opacity={0.65} />
          </g>
        </g>
      ))}
      {detailOnly(model, stroke, strokeW)}
    </>
  );
}

/** Clinical uses FDI-specific paths; wireframe uses textbook silhouettes + line sculpture (original combo). */
export const ToothGlyph = memo(function ToothGlyph({
  fdi,
  kind,
  gradientId,
  selected,
  upper,
  mirrored,
  upsideDown,
  className = 'w-8 h-[4.85rem]',
  variant = 'clinical',
}: ToothGlyphProps) {
  const lastDigit = Number(fdi[1]);
  const model: ToothPathModel | null =
    variant === 'clinical'
      ? getToothPathModel(fdi, kind, upper)
      : getTextbookToothPathModel(kind, upper, lastDigit);
  const paint = getToothGlyphPaint(variant, gradientId, selected);
  const { showClinicalGradient, filter, structuralMode } = paint;

  if (!model) {
    return (
      <svg viewBox="0 0 36 78" className={`${className} shrink-0`} aria-hidden>
        <text x="4" y="40" fontSize="8" fill="currentColor" opacity="0.35">
          ?
        </text>
      </svg>
    );
  }

  const body = structuralMode === 'wireframe' ? renderWireframe(model, paint, kind) : renderClinicalFill(model, paint);

  return (
    <svg
      viewBox="0 0 36 78"
      className={`${className} shrink-0`}
      style={{ filter }}
      aria-hidden
    >
      {showClinicalGradient && (
        <defs>
          <radialGradient id={gradientId} cx="45%" cy="35%" r="65%">
            <stop offset="0%" stopColor={selected ? '#cffafe' : '#ffffff'} />
            <stop offset="55%" stopColor={selected ? '#5eead4' : '#e0f2fe'} />
            <stop offset="100%" stopColor={selected ? '#0e7490' : '#93c5fd'} />
          </radialGradient>
        </defs>
      )}
      <g
        transform={[
          mirrored ? 'translate(36 0) scale(-1 1)' : '',
          upsideDown ? 'translate(0 78) scale(1 -1)' : '',
        ]
          .filter(Boolean)
          .join(' ') || undefined}
      >
        {body}
      </g>
    </svg>
  );
});
