// ToothChart.jsx — Interactive dental chart (odontogram) for the Smile Audit.
//
// Self-contained: it draws its own 32-tooth SVG, so it no longer depends on a
// pre-rendered SVG string. (The previous build relied on toothmap.js, whose SVG
// carried no data hooks — nothing was selectable, so the chart "didn't work".)
//
// The patient marks the tooth or teeth to be addressed. Quick options cover the
// non-tooth-specific cases: "Whole mouth" (e.g. whitening) and "Not a specific
// tooth" (e.g. bruxism, a general concern). When two or more teeth are marked,
// the chart asks for the LEVEL and URGENCY of the problem.
//
// onChange payload:
//   { teeth:[universal#…], scope:'specific'|'whole'|'none',
//     level: 0-10|null, urgency:'today'|'week'|'month'|'routine'|null }
const { useState: useTC, useEffect: useTCE } = React;

// Universal (1-32) → FDI (11-48).
const UNIVERSAL_TO_FDI = (() => {
  const map = {};
  for (let i = 1;  i <= 8;  i++) map[i] = 19 - i;        // 1→18 … 8→11
  for (let i = 9;  i <= 16; i++) map[i] = 20 + (i - 8);  // 9→21 … 16→28
  for (let i = 17; i <= 24; i++) map[i] = 39 - (i - 17); // 17→38 … 24→31
  for (let i = 25; i <= 32; i++) map[i] = 40 + (i - 24); // 25→41 … 32→48
  return map;
})();

const ALL_TEETH = Array.from({ length: 32 }, (_, i) => i + 1);

// Position within the tooth's own quadrant: 0 = central incisor … 7 = 3rd molar.
function quadrantIndex(n) {
  if (n <= 8)  return 8 - n;
  if (n <= 16) return n - 9;
  if (n <= 24) return 24 - n;
  return n - 25;
}
function toothClass(n) {
  const q = quadrantIndex(n);
  if (q <= 1) return 'incisor';
  if (q === 2) return 'canine';
  if (q <= 4) return 'premolar';
  return 'molar';
}
const CLASS_W = { incisor: 23, canine: 27, premolar: 30, molar: 37 };

// Build the two arches once. Upper arch bows up in the middle, lower bows down.
const LAYOUT = (() => {
  const VIEW_W = 720, slotW = 42, marginX = (VIEW_W - 16 * slotW) / 2;
  const archK = 13, h = 58;
  const upper = [], lower = [];
  for (let pos = 0; pos < 16; pos++) {
    const cx = marginX + slotW / 2 + pos * slotW;
    const archY = archK * Math.pow((pos - 7.5) / 7.5, 2);
    const un = pos + 1;        // upper: 1..16 left→right (patient's right→left)
    const ln = 32 - pos;       // lower: 32..17 left→right
    upper.push({ n: un, cls: toothClass(un), cx, top: 54 + archY, w: CLASS_W[toothClass(un)], h });
    lower.push({ n: ln, cls: toothClass(ln), cx, top: 230 - archY, w: CLASS_W[toothClass(ln)], h });
  }
  return { upper, lower, h };
})();

// A simple tooth silhouette: rounded crown with a softly waved biting edge.
function toothD(cx, top, w, h) {
  const l = cx - w / 2, r = cx + w / 2, b = top + h;
  const k = Math.min(8, w * 0.34);
  return `M${l} ${top + k}Q${l} ${top} ${l + k} ${top}`
       + `L${r - k} ${top}Q${r} ${top} ${r} ${top + k}`
       + `L${r} ${b - k}Q${r} ${b} ${r - k} ${b - 3}`
       + `Q${cx} ${b - 9} ${l + k} ${b - 3}`
       + `Q${l} ${b} ${l} ${b - k}Z`;
}

// 0 = barely tinted, 10 = full alert red. var(--seal) is rgb(184,73,44).
function severityColor(level) {
  const c = Math.max(0, Math.min(10, level || 0));
  return `rgba(184, 73, 44, ${(0.32 + (c / 10) * 0.55).toFixed(3)})`;
}

const LEVELS = [
  { key: 'mild',     label: 'Mild',     value: 3 },
  { key: 'moderate', label: 'Moderate', value: 6 },
  { key: 'severe',   label: 'Severe',   value: 9 },
];
const URGENCIES = [
  { key: 'today',   label: 'Today' },
  { key: 'week',    label: 'This week' },
  { key: 'month',   label: 'This month' },
  { key: 'routine', label: 'Routine' },
];

function ChipRow({ options, value, onPick, getKey }) {
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
      {options.map(o => {
        const k = getKey(o);
        const active = value === k;
        return (
          <button key={k} type="button" onClick={() => onPick(k)} aria-pressed={active}
            style={{
              fontSize: 13, fontWeight: 600, padding: '7px 13px', borderRadius: 999,
              cursor: 'pointer',
              border: `1px solid ${active ? 'var(--seal)' : 'var(--ink-5)'}`,
              background: active ? 'var(--seal)' : 'var(--paper)',
              color: active ? 'var(--paper)' : 'var(--ink-2)',
            }}>{o.label}</button>
        );
      })}
    </div>
  );
}

function ToothChart({ teeth = [], scope = 'specific', level = null, urgency = null,
                      onChange, size = 'md' }) {
  const [numbering, setNumbering] = useTC(() => {
    try { return localStorage.getItem('td_numbering') || 'universal'; } catch { return 'universal'; }
  });
  const [hover, setHover] = useTC(null);
  useTCE(() => { try { localStorage.setItem('td_numbering', numbering); } catch {} }, [numbering]);

  const selectedSet = new Set(scope === 'whole' ? ALL_TEETH : scope === 'none' ? [] : teeth);
  const displayNum = (n) => (numbering === 'fdi' ? UNIVERSAL_TO_FDI[n] : n);

  const emit = (next) => {
    if (!onChange) return;
    onChange({
      teeth:   next.teeth   !== undefined ? next.teeth   : teeth,
      scope:   next.scope   !== undefined ? next.scope   : scope,
      level:   next.level   !== undefined ? next.level   : level,
      urgency: next.urgency !== undefined ? next.urgency : urgency,
    });
  };

  const toggleTooth = (n) => {
    const base = scope === 'specific' ? teeth : [];
    const nextTeeth = base.includes(n)
      ? base.filter(x => x !== n)
      : [...base, n].sort((a, b) => a - b);
    emit({ teeth: nextTeeth, scope: 'specific' });
  };
  const selectWhole = () => emit({ teeth: ALL_TEETH.slice(), scope: 'whole' });
  const selectNone  = () => emit({ teeth: [], scope: 'none', level: null, urgency: null });
  const clearAll    = () => emit({ teeth: [], scope: 'specific', level: null, urgency: null });

  const fillFor = (n) => {
    if (selectedSet.has(n)) return level == null ? 'rgba(184,73,44,0.58)' : severityColor(level);
    return hover === n ? 'var(--bone)' : '#FCFBF9';
  };

  const count = selectedSet.size;
  const askProblem = count >= 2; // "if more than one tooth is addressed, inquire…"

  const renderRow = (row, isUpper) => row.map(t => {
    const sel = selectedSet.has(t.n);
    return (
      <g key={t.n}>
        <path d={toothD(t.cx, t.top, t.w, t.h)}
          fill={fillFor(t.n)}
          stroke={sel ? 'var(--seal)' : 'var(--ink-4)'}
          strokeWidth={sel ? 2 : 1.1}
          style={{ cursor: 'pointer', transition: 'fill .12s ease' }}
          tabIndex={0} role="button" aria-pressed={sel}
          aria-label={`Tooth ${displayNum(t.n)}${sel ? ', marked' : ''}`}
          onClick={() => toggleTooth(t.n)}
          onMouseEnter={() => setHover(t.n)}
          onMouseLeave={() => setHover(h => (h === t.n ? null : h))}
          onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggleTooth(t.n); } }}>
          <title>Tooth {displayNum(t.n)}</title>
        </path>
        <text x={t.cx} y={isUpper ? t.top - 6 : t.top + t.h + 13}
          textAnchor="middle" fontSize="11" fontFamily="ui-monospace, 'SF Mono', monospace"
          fill={sel ? 'var(--seal)' : 'var(--ink-3)'} fontWeight={sel ? 700 : 400}
          style={{ pointerEvents: 'none' }}>{displayNum(t.n)}</text>
      </g>
    );
  });

  const quickBtn = (active) => ({
    fontSize: 13, fontWeight: 600, padding: '8px 13px', borderRadius: 999, cursor: 'pointer',
    border: `1px solid ${active ? 'var(--ink-1)' : 'var(--ink-5)'}`,
    background: active ? 'var(--ink-1)' : 'var(--paper)',
    color: active ? 'var(--paper)' : 'var(--ink-2)',
    display: 'inline-flex', alignItems: 'center', gap: 6,
  });

  let summary;
  if (scope === 'whole') summary = 'Whole mouth marked.';
  else if (scope === 'none') summary = 'Marked as a general concern — not one specific tooth.';
  else if (teeth.length) summary = `Marked: ${teeth.map(displayNum).join(', ')}`;
  else summary = 'Tap the tooth or teeth that need attention — or use an option above.';

  return (
    <div style={{ position: 'relative' }}>
      {/* Quick options + numbering toggle */}
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center',
                    justifyContent: 'space-between', marginBottom: 10 }}>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
          <button type="button" onClick={selectWhole} style={quickBtn(scope === 'whole')}>
            {window.Icon && <Icon d={ICONS.tooth} size={15}/>} Whole mouth
          </button>
          <button type="button" onClick={selectNone} style={quickBtn(scope === 'none')}>
            Not a specific tooth
          </button>
          {count > 0 && (
            <button type="button" onClick={clearAll}
              style={{ ...quickBtn(false), border: '1px dashed var(--ink-4)' }}>
              {window.Icon && <Icon d={ICONS.x} size={14}/>} Clear
            </button>
          )}
        </div>
        <div role="group" aria-label="Tooth numbering"
          style={{ display: 'inline-flex', border: '1px solid var(--ink-5)', borderRadius: 8, overflow: 'hidden' }}>
          {['universal', 'fdi'].map(k => (
            <button key={k} type="button" onClick={() => setNumbering(k)}
              style={{
                fontSize: 12, padding: '5px 10px', cursor: 'pointer', border: 'none',
                background: numbering === k ? 'var(--ink-1)' : 'var(--paper)',
                color: numbering === k ? 'var(--paper)' : 'var(--ink-2)',
              }}>{k === 'universal' ? 'Universal' : 'FDI'}</button>
          ))}
        </div>
      </div>

      {/* The odontogram */}
      <div style={{ maxWidth: size === 'sm' ? 440 : 680, margin: '0 auto' }}>
        <svg viewBox="0 0 720 332" width="100%" style={{ height: 'auto', userSelect: 'none', touchAction: 'manipulation' }}
          role="group" aria-label="Dental chart — tap teeth to mark them">
          {/* orientation */}
          <text x="20"  y="20" fontSize="11" fill="var(--ink-4)" fontWeight="600"
            letterSpacing="0.06em">YOUR RIGHT</text>
          <text x="700" y="20" textAnchor="end" fontSize="11" fill="var(--ink-4)" fontWeight="600"
            letterSpacing="0.06em">YOUR LEFT</text>
          <text x="360" y="20" textAnchor="middle" fontSize="11" fill="var(--ink-4)"
            fontWeight="600" letterSpacing="0.08em">UPPER</text>
          <text x="360" y="326" textAnchor="middle" fontSize="11" fill="var(--ink-4)"
            fontWeight="600" letterSpacing="0.08em">LOWER</text>
          <line x1="360" y1="40" x2="360" y2="300" stroke="var(--ink-4)" strokeWidth="1"
            strokeDasharray="2 5" opacity="0.5"/>
          {renderRow(LAYOUT.upper, true)}
          {renderRow(LAYOUT.lower, false)}
        </svg>
      </div>

      {/* Summary */}
      <div style={{ marginTop: 6, padding: '9px 12px', background: 'var(--bone)', borderRadius: 10,
                    fontSize: 13, color: 'var(--ink-2)' }}>
        <strong style={{ color: 'var(--ink-1)' }}>{summary}</strong>
      </div>

      {/* Problem panel — appears once two or more teeth are marked */}
      {askProblem && (
        <div className="card card-paper" style={{ marginTop: 10, display: 'grid', gap: 'var(--s-3)' }}>
          <div>
            <div style={{ fontFamily: 'var(--font-display)', fontSize: 16, fontWeight: 500 }}>
              You marked {count === 32 ? 'your whole mouth' : `${count} teeth`} — tell us about the problem
            </div>
            <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 2 }}>
              This helps us order what a dentist would address first.
            </div>
          </div>
          <div>
            <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--ink-3)', marginBottom: 6 }}>
              How bad is it?
            </div>
            <ChipRow options={LEVELS} value={LEVELS.find(l => l.value === level)?.key || null}
              getKey={(o) => o.key}
              onPick={(k) => emit({ level: LEVELS.find(l => l.key === k).value })}/>
          </div>
          <div>
            <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--ink-3)', marginBottom: 6 }}>
              How soon does it need attention?
            </div>
            <ChipRow options={URGENCIES} value={urgency} getKey={(o) => o.key}
              onPick={(k) => emit({ urgency: k })}/>
          </div>
        </div>
      )}
    </div>
  );
}

window.ToothChart = ToothChart;
window.UNIVERSAL_TO_FDI = UNIVERSAL_TO_FDI;
