// ──── ODONTOGRAM ────  (SVGs: github.com/ZoliQua/React-Odontogram-Modul, MIT)

const _UR = [18,17,16,15,14,13,12,11];
const _UL = [21,22,23,24,25,26,27,28];
const _LR = [48,47,46,45,44,43,42,41];
const _LL = [31,32,33,34,35,36,37,38];
const _ALL   = [..._UR,..._UL,..._LL,..._LR];
const _UPPER = [..._UR,..._UL];
const _LOWER = [..._LL,..._LR];
const _UF = [13,12,11,21,22,23];
const _UM = [18,17,16,15,14,24,25,26,27,28];
const _LF = [43,42,41,31,32,33];
const _LM = [48,47,46,45,44,34,35,36,37,38];

const _BASE_OPTS = [
  {v:'permanent',l:'Kalıcı Diş'},{v:'milk',l:'Süt Dişi'},{v:'missing',l:'Eksik'},
  {v:'implant',l:'İmplant'},{v:'extracted',l:'Çekildi'},{v:'extraction-plan',l:'Çekim Planı'},
];
const _CROWN_OPTS = [
  {v:'natural',l:'Doğal'},{v:'full',l:'Tam Kron'},{v:'partial',l:'Parsiyel Kron'},
  {v:'pfm',l:'PFM'},{v:'metal',l:'Metal'},{v:'zirconia',l:'Zirkonyum'},
  {v:'veneer',l:'Veneer'},{v:'needed',l:'Kron Gerekli'},
];
const _FILL_OPTS = [
  {v:'none',l:'Dolgu Yok'},{v:'amalgam',l:'Amalgam'},{v:'composite',l:'Kompozit'},
  {v:'ceramic',l:'Seramik'},{v:'glass',l:'Cam İyonomer'},{v:'temp',l:'Geçici Dolgu'},
];
const _ROOT_OPTS = [
  {v:'healthy',l:'Sağlıklı Kök'},{v:'canal',l:'Kanal Tedavisi'},
  {v:'resection',l:'Apikal Rezeksiyon'},{v:'fracture',l:'Kök Kırığı'},{v:'resorption',l:'Rezorpsiyon'},
];
const _MOB_OPTS = [
  {v:'0',l:'Yok (0)'},{v:'1',l:'Derece I'},{v:'2',l:'Derece II'},{v:'3',l:'Derece III'},
];
const _IMPL_CROWN_OPTS = [
  {v:'none',l:'Yok'},{v:'healing-abutment',l:'Healing Abutment'},
  {v:'zircon',l:'Zirkonyum Kron'},{v:'metal',l:'Metal-Seramik Kron'},
  {v:'temporary',l:'Geçici Kron'},{v:'locator',l:'Locator'},
  {v:'locator-prosthesis',l:'Locator + Protez Diş'},
  {v:'bar',l:'Bar İmplant'},{v:'bar-prosthesis',l:'Bar + Protez Diş'},
];
const _GROUP_ADD = [
  {v:'uf-zirconia',l:'Üst 12-22 Zirkonyum'},{v:'ua-zirconia',l:'Üst Tümü Zirkonyum'},
  {v:'lf-zirconia',l:'Alt 12-22 Zirkonyum'},{v:'uf-pfm',l:'Üst 12-22 PFM'},
  {v:'ua-canal',l:'Üst Kanal Tedavisi'},{v:'la-canal',l:'Alt Kanal Tedavisi'},
];

const _CROWN_CLR = {full:'#f59e0b',partial:'#fbbf24',pfm:'#8b5cf6',metal:'#9ca3af',zirconia:'#2B47E8',veneer:'#ec4899'};
const _FILL_CLR  = {amalgam:'#64748b',composite:'#3b82f6',ceramic:'#a78bfa',glass:'#10b981',temp:'#f97316'};
const _IMPL_CLR  = {'healing-abutment':'#e2e8f0',zircon:'#2B47E8',metal:'#9ca3af',temporary:'#f97316',locator:'#8b5cf6','locator-prosthesis':'#a78bfa',bar:'#64748b','bar-prosthesis':'#475569'};
const _SURF_LABELS = {O:'Oklüzal',B:'Bukkal',L:'Lingual',M:'Mezial',D:'Distal'};

const _odoDefault = () => ({
  base:'permanent', crown:'natural',
  caries:[], filling:'none', fillingSurfaces:[], fissureSealing:false,
  root:'healthy', mobility:'0', pulpInflam:false, bruxism:false, bridgeUnit:'none',
  implantCrown:'none',
});

// ── SVG helpers ──────────────────────────────────────────────────
// Template: Q1(11-18)=none | Q2(21-28)=mirrorX | Q3(31-38)=mirrorX+mirrorY | Q4(41-48)=mirrorY
function _lateralSrc(num) {
  const t = num % 10;
  if (t <= 2) return 'teeth-svgs/11.svg';
  if (t === 3) return 'teeth-svgs/13.svg';
  if (t <= 5) return 'teeth-svgs/14.svg';
  return 'teeth-svgs/16.svg';
}
function _occlSrc(num) {
  const t = num % 10;
  if (t <= 3) return null;
  if (t <= 5) return 'teeth-svgs/14_occl.svg';
  return 'teeth-svgs/16_occl.svg';
}
function _lateralTransform(num) {
  const q = Math.floor(num / 10);
  if (q === 2) return 'scaleX(-1)';
  if (q === 3) return 'scaleX(-1) scaleY(-1)';
  if (q === 4) return 'scaleY(-1)';
  return 'none';
}
function _occlTransform(num) {
  const q = Math.floor(num / 10);
  return (q === 2 || q === 3) ? 'scaleX(-1)' : 'none';
}

// ── Note diff ────────────────────────────────────────────────────
function _buildNote(oldSaved, newTeeth) {
  const changes = [];
  _ALL.forEach(n => {
    const old = oldSaved[String(n)] || _odoDefault();
    const cur = newTeeth[n] || _odoDefault();
    const diff = [];
    if (old.base !== cur.base)
      diff.push(_BASE_OPTS.find(o=>o.v===cur.base)?.l);
    if (old.crown !== cur.crown && cur.crown !== 'natural')
      diff.push(_CROWN_OPTS.find(o=>o.v===cur.crown)?.l);
    if (cur.base==='implant' && old.implantCrown !== cur.implantCrown && cur.implantCrown !== 'none')
      diff.push(_IMPL_CROWN_OPTS.find(o=>o.v===cur.implantCrown)?.l);
    if (old.root !== cur.root && cur.root !== 'healthy')
      diff.push(_ROOT_OPTS.find(o=>o.v===cur.root)?.l);
    const nc = (cur.caries||[]).filter(s=>!(old.caries||[]).includes(s));
    if (nc.length) diff.push('Çürük(' + nc.join('') + ')');
    if (old.filling !== cur.filling && cur.filling !== 'none')
      diff.push((_FILL_OPTS.find(o=>o.v===cur.filling)?.l||'') + ' dolgu');
    if (diff.length) changes.push(n + ': ' + diff.filter(Boolean).join(', '));
  });
  if (!changes.length) return null;
  const ds = new Date().toLocaleDateString('tr-TR',{day:'2-digit',month:'2-digit',year:'numeric'});
  const s = changes.slice(0,4).join('; ') + (changes.length>4 ? ' (+' + (changes.length-4) + ')' : '');
  return '\n[' + ds + '] Odontogram — ' + s + '.';
}

// ── Tooth cell ───────────────────────────────────────────────────
function OdoToothCell({ num, tooth, selected, onSelect }) {
  const [hovered, setHovered] = React.useState(false);
  const q = Math.floor(num / 10);
  const isUpper = q === 1 || q === 2;
  const base = tooth.base || 'permanent';
  const mobLabel = tooth.mobility && tooth.mobility !== '0' ? tooth.mobility : null;

  const numColor = (base==='missing'||base==='extracted') ? '#94a3b8'
    : base==='implant' ? '#2B47E8'
    : selected ? 'var(--accent)' : 'var(--text-mute)';

  const isDashed = base === 'extraction-plan';

  const mkCard = (content, transparent) => (
    <div style={{
      borderRadius: 8,
      border: transparent ? '2px solid transparent'
        : isDashed ? '2px dashed #ef4444'
        : selected ? '2px solid var(--accent)'
        : hovered  ? '2px solid #93a8f4'
        : '2px solid var(--line)',
      background: transparent ? 'transparent'
        : selected ? 'rgba(43,71,232,0.08)'
        : hovered  ? 'rgba(43,71,232,0.03)' : 'transparent',
      transition: 'border-color 0.14s, background 0.14s',
      overflow: 'hidden', lineHeight: 0, padding: 2, position: 'relative',
    }}>{content}</div>
  );

  const numEl = (
    <span className="odont-num" style={{color:numColor, fontWeight:selected?700:400, position:'relative'}}>
      {num}
      {mobLabel && <span style={{position:'absolute',top:-4,right:-8,fontSize:7,background:'#f59e0b',color:'white',borderRadius:3,padding:'1px 2px',fontWeight:700}}>M{mobLabel}</span>}
    </span>
  );

  const lt = _lateralTransform(num);
  const ot = _occlTransform(num);
  const ls = _lateralSrc(num);
  const os = _occlSrc(num);
  const crownClr = _CROWN_CLR[tooth.crown];
  const fillClr  = _FILL_CLR[tooth.filling];
  const hasCaries = tooth.caries && tooth.caries.length > 0;
  const implClr = _IMPL_CLR[tooth.implantCrown] || '#2B47E8';
  const ic = tooth.implantCrown || 'none';

  // Lateral view content
  let lateralEl;
  if (base === 'missing' || base === 'extracted') {
    lateralEl = mkCard(
      <svg className="odont-lateral-svg" viewBox="0 0 36 64" style={{display:'block'}}>
        <line x1="8" y1="12" x2="28" y2="52" stroke="#94a3b8" strokeWidth="4" strokeLinecap="round"/>
        <line x1="28" y1="12" x2="8" y2="52" stroke="#94a3b8" strokeWidth="4" strokeLinecap="round"/>
      </svg>
    );
  } else if (base === 'implant') {
    lateralEl = mkCard(
      <svg className="odont-lateral-svg" viewBox="0 0 36 64" style={{display:'block',transform:lt}}>
        <path d="M35.6,16.2l-2.5,1.2c-2.3,1.4,0,8.6-1.8,10.8,0,4.4-4.1,3.5-5.3,3.4-3.5-.2-11.8,0-15.8,0s-4.5-2.9-4.6-2.8c-1.9,0-2-11.4-2-11.4l-1.3-2c-.2-.4-2.1-.9-2.1-1.4V0h35.5v16.2h-.1Z" fill="#fdecc5"/>
        <path d="M36.1,17.2c-1,1-2.5,1.7-3,3-1,3.5-.2,7.6-1.5,11-1.9,5.1-5.6.4-9.2.5-3.6,0-7.6-.2-11,.5-2.1.6-4.3,2.6-6.5,1.2C-.4,29.7,3.2,20.8,1.2,15.8c-.2-.9-1.9-2.3-1-2.8,1-.5,3.8,1,4.2,2.2,1.9,3.7-1.8,13.9,3.2,15.2,2.4.3,7.7-.6,12.2-.9,3.4-.6,8.7.9,10.6-2.3,1.9-3.2-.1-8.1,2.3-11.1s5.1-1.2,3.5.9h0v.2h-.1Z" fill="#f79f9a"/>
        <rect x="13" y="22" width="10" height="32" rx="3" fill={implClr} opacity="0.88"/>
        {[26,30,34,38,42,46].map(y => (
          <rect key={y} x="11" y={y} width="14" height="2" rx="1" fill={implClr} opacity="0.5"/>
        ))}
        <rect x="14" y="16" width="8" height="8" rx="2" fill={implClr} opacity="0.9"/>
        {ic !== 'none' && ic !== 'healing-abutment' && (
          <ellipse cx="18" cy="13" rx="9" ry="3.5" fill={implClr} stroke="rgba(255,255,255,0.7)" strokeWidth="0.8"/>
        )}
        {ic === 'healing-abutment' && (
          <circle cx="18" cy="13" r="5" fill="#e2e8f0" stroke="#94a3b8" strokeWidth="1.2"/>
        )}
      </svg>
    );
  } else {
    lateralEl = mkCard(
      <div style={{position:'relative',lineHeight:0}}>
        <img src={ls} className="odont-lateral-svg" style={{display:'block',transform:lt}} alt=""/>
        {crownClr && <div style={{position:'absolute',inset:0,background:crownClr,opacity:0.17,pointerEvents:'none'}}/>}
        {hasCaries && <div style={{position:'absolute',inset:0,background:'#ef4444',opacity:0.13,pointerEvents:'none'}}/>}
      </div>
    );
  }

  // Occlusal view content (premolars + molars only; placeholder for others to keep alignment)
  let occlEl;
  if (!os) {
    occlEl = mkCard(<div className="odont-svg"/>, true);
  } else if (base === 'missing' || base === 'extracted') {
    occlEl = mkCard(<div className="odont-svg"/>);
  } else if (base === 'implant') {
    occlEl = mkCard(
      <svg className="odont-svg" viewBox="0 0 42 42" style={{display:'block'}}>
        <ellipse cx="21" cy="21" rx="13" ry="13" fill={implClr} opacity="0.75"/>
        <ellipse cx="21" cy="21" rx="6" ry="6" fill="white" opacity="0.5"/>
      </svg>
    );
  } else {
    occlEl = mkCard(
      <div style={{position:'relative',lineHeight:0}}>
        <img src={os} className="odont-svg" style={{display:'block',transform:ot}} alt=""/>
        {hasCaries && <div style={{position:'absolute',inset:0,background:'#ef4444',opacity:0.16,pointerEvents:'none'}}/>}
        {fillClr && tooth.filling!=='none' && <div style={{position:'absolute',inset:0,background:fillClr,opacity:0.22,pointerEvents:'none'}}/>}
        {crownClr && <div style={{position:'absolute',inset:0,background:crownClr,opacity:0.1,pointerEvents:'none'}}/>}
      </div>
    );
  }

  return (
    <div className="odont-tooth"
      onClick={onSelect}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      style={{cursor:'pointer',userSelect:'none'}}>
      {isUpper && numEl}
      {!isUpper && occlEl}
      {lateralEl}
      {isUpper && occlEl}
      {!isUpper && numEl}
    </div>
  );
}

// ── Section + Surface buttons ─────────────────────────────────────
function OdoSection({ title, open, onToggle, children }) {
  return (
    <div style={{border:'1px solid var(--line)',borderRadius:10,overflow:'hidden',marginBottom:8}}>
      <button type="button" onClick={onToggle}
        style={{width:'100%',display:'flex',justifyContent:'space-between',alignItems:'center',padding:'10px 14px',background:'var(--surface-2)',border:'none',cursor:'pointer',fontWeight:700,fontSize:13,color:'var(--text)',fontFamily:'inherit'}}>
        {title}
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"
          style={{transform:open?'rotate(180deg)':'rotate(0deg)',transition:'transform 0.2s'}}>
          <polyline points="6 9 12 15 18 9"/>
        </svg>
      </button>
      {open && <div style={{padding:'12px 14px'}}>{children}</div>}
    </div>
  );
}

function SurfBtns({ surfaces, activeArr, onChange }) {
  return (
    <div style={{display:'flex',gap:4,flexWrap:'wrap',marginTop:6}}>
      {surfaces.map(s => {
        const on = activeArr && activeArr.includes(s);
        return (
          <button key={s} type="button" onClick={() => onChange(s)}
            style={{padding:'4px 8px',borderRadius:6,border:'1.5px solid',fontSize:11,fontWeight:700,cursor:'pointer',
              borderColor: on ? 'var(--accent)' : 'var(--line)',
              background: on ? 'var(--accent)' : 'var(--surface)',
              color: on ? 'white' : 'var(--text-mute)',
              fontFamily:'Inter,sans-serif'}}>
            {s}<span style={{fontWeight:400,marginLeft:2,opacity:.7}}>{_SURF_LABELS[s]?.slice(0,3)}</span>
          </button>
        );
      })}
    </div>
  );
}

// ── Controls panel ────────────────────────────────────────────────
function OdoControls({ teeth, selected, onSetSelected, onUpdateTooth, onApplyGroup }) {
  const [openSections, setOpenSections] = React.useState({status:true,detail:true,caries:true,fill:true,root:true,other:false});
  const [groupAdd, setGroupAdd] = React.useState(_GROUP_ADD[0].v);
  const toggle = (k) => setOpenSections(s => ({...s,[k]:!s[k]}));

  const activeNum = selected.length === 1 ? selected[0] : null;
  const tooth = activeNum ? (teeth[activeNum] || _odoDefault()) : null;
  const multi = selected.length > 1;

  const upd = (k, v) => { if (selected.length === 0) return; onUpdateTooth(selected, k, v); };
  const toggleSurf = (k, surf) => { if (selected.length === 0) return; onUpdateTooth(selected, k, null, surf); };

  const groupBtns = [
    {l:'Tümü',g:'all',nums:_ALL},{l:'Üst',g:'upper',nums:_UPPER},{l:'Alt',g:'lower',nums:_LOWER},
    {l:'Üst Ön',g:'uf',nums:_UF},{l:'Üst Azı',g:'um',nums:_UM},
    {l:'Alt Ön',g:'lf',nums:_LF},{l:'Alt Azı',g:'lm',nums:_LM},
  ];

  const handleGroupAdd = () => {
    const v = groupAdd;
    let nums = [], props = {};
    if (v === 'uf-zirconia') { nums = _UF; props = {crown:'zirconia'}; }
    else if (v === 'ua-zirconia') { nums = _UPPER; props = {crown:'zirconia'}; }
    else if (v === 'lf-zirconia') { nums = _LF; props = {crown:'zirconia'}; }
    else if (v === 'uf-pfm') { nums = _UF; props = {crown:'pfm'}; }
    else if (v === 'ua-canal') { nums = _UPPER; props = {root:'canal'}; }
    else if (v === 'la-canal') { nums = _LOWER; props = {root:'canal'}; }
    Object.entries(props).forEach(([k,val]) => onUpdateTooth(nums, k, val));
  };

  const CS = {label:{fontSize:11,fontWeight:600,color:'var(--text-mute)',display:'block',marginBottom:4}};
  const SC = {card:{flex:'1 1 210px',minWidth:190,maxWidth:360}};
  const SEL = {width:'100%',padding:'6px 8px',border:'1px solid var(--line)',borderRadius:7,fontSize:12,fontFamily:'inherit',background:'var(--surface)',color:'var(--text)'};

  const isImplant = tooth?.base === 'implant';

  return (
    <div style={{borderTop:'1px solid var(--line)',background:'var(--surface-2)'}}>

      {/* Header bar */}
      <div style={{padding:'10px 16px',borderBottom:'1px solid var(--line)',display:'flex',alignItems:'center',gap:12,flexWrap:'wrap'}}>
        <span style={{fontWeight:800,fontSize:13,color:'var(--text)',flexShrink:0}}>Kontroller</span>
        <div style={{display:'flex',alignItems:'center',gap:6,flexShrink:0}}>
          <span style={{fontSize:11,color:'var(--text-mute)'}}>Aktif:</span>
          {selected.length === 0 && <span style={{background:'var(--line)',borderRadius:20,padding:'1px 8px',fontSize:11}}>—</span>}
          {selected.length === 1 && <span style={{background:'var(--accent)',color:'white',borderRadius:20,padding:'1px 8px',fontWeight:700,fontSize:11}}>{selected[0]}</span>}
          {selected.length > 1 && <span style={{background:'var(--accent)',color:'white',borderRadius:20,padding:'1px 8px',fontWeight:700,fontSize:11}}>{selected.length} diş</span>}
        </div>
        <button type="button" className="btn btn--ghost btn--sm" style={{fontSize:11,padding:'3px 8px',flexShrink:0}}
          onClick={() => onSetSelected([])}>Seçimi Temizle</button>
        <div style={{display:'flex',flexWrap:'wrap',gap:4,flex:1}}>
          {groupBtns.map(b => (
            <button key={b.g} type="button" onClick={() => onSetSelected(b.nums)}
              style={{fontSize:10,padding:'3px 7px',border:'1px solid var(--line)',borderRadius:6,cursor:'pointer',
                background: b.nums.every(n => selected.includes(n)) ? 'var(--accent)' : 'var(--surface)',
                color: b.nums.every(n => selected.includes(n)) ? 'white' : 'var(--text)',
                fontFamily:'inherit',fontWeight:500}}>
              {b.l}
            </button>
          ))}
        </div>
      </div>

      {/* Sections row */}
      <div style={{display:'flex',flexWrap:'wrap',gap:10,padding:'12px 16px',alignItems:'flex-start'}}>

        {/* Durumlar */}
        <div style={SC.card}>
          <OdoSection title="Durumlar" open={openSections.status} onToggle={() => toggle('status')}>
            <div style={{display:'flex',flexWrap:'wrap',gap:4,marginBottom:10}}>
              {[{l:'Sıfırla',a:'reset'},{l:'Süt Dişleri',a:'milk'},{l:'Karışık Dişlenme',a:'mixed'},{l:'Dişsiz',a:'edentulous'}].map(b => (
                <button key={b.a} type="button" className="btn btn--ghost btn--sm" style={{fontSize:11,padding:'3px 8px'}}
                  onClick={() => onApplyGroup(b.a)}>{b.l}</button>
              ))}
            </div>
            <label style={CS.label}>Ekle:</label>
            <div style={{display:'flex',gap:6,alignItems:'center'}}>
              <select value={groupAdd} onChange={e => setGroupAdd(e.target.value)}
                style={{flex:1,padding:'5px 8px',border:'1px solid var(--line)',borderRadius:7,fontSize:11,fontFamily:'inherit',background:'var(--surface)',color:'var(--text)'}}>
                {_GROUP_ADD.map(o => <option key={o.v} value={o.v}>{o.l}</option>)}
              </select>
              <button type="button" className="btn btn--accent btn--sm" style={{fontSize:11,padding:'4px 10px',flexShrink:0}}
                onClick={handleGroupAdd}>Tamam</button>
            </div>
          </OdoSection>
        </div>

        {/* Diş Detayı */}
        <div style={SC.card}>
          <OdoSection title="Diş Detayı" open={openSections.detail} onToggle={() => toggle('detail')}>
            {!tooth && !multi && <p style={{fontSize:12,color:'var(--text-mute)',margin:0}}>Bir diş seçin.</p>}
            {(tooth || multi) && (
              <>
                <div style={{marginBottom:10}}>
                  <label style={CS.label}>Taban</label>
                  <select value={tooth?.base || ''} onChange={e => upd('base', e.target.value)} style={SEL}>
                    {_BASE_OPTS.map(o => <option key={o.v} value={o.v}>{o.l}</option>)}
                  </select>
                </div>
                {isImplant ? (
                  <div>
                    <label style={CS.label}>İmplant Üst Yapısı</label>
                    <select value={tooth?.implantCrown || 'none'} onChange={e => upd('implantCrown', e.target.value)} style={SEL}>
                      {_IMPL_CROWN_OPTS.map(o => <option key={o.v} value={o.v}>{o.l}</option>)}
                    </select>
                    {tooth?.implantCrown && _IMPL_CLR[tooth.implantCrown] && (
                      <div style={{display:'flex',alignItems:'center',gap:6,marginTop:4}}>
                        <span style={{width:10,height:10,borderRadius:'50%',background:_IMPL_CLR[tooth.implantCrown],display:'inline-block'}}/>
                        <span style={{fontSize:10,color:'var(--text-mute)'}}>{_IMPL_CROWN_OPTS.find(o=>o.v===tooth.implantCrown)?.l}</span>
                      </div>
                    )}
                  </div>
                ) : (
                  <div>
                    <label style={CS.label}>Kron Tipi</label>
                    <select value={tooth?.crown || ''} onChange={e => upd('crown', e.target.value)} style={SEL}>
                      {_CROWN_OPTS.map(o => <option key={o.v} value={o.v}>{o.l}</option>)}
                    </select>
                    {tooth?.crown && _CROWN_CLR[tooth.crown] && (
                      <div style={{display:'flex',alignItems:'center',gap:6,marginTop:4}}>
                        <span style={{width:10,height:10,borderRadius:'50%',background:_CROWN_CLR[tooth.crown],display:'inline-block'}}/>
                        <span style={{fontSize:10,color:'var(--text-mute)'}}>{_CROWN_OPTS.find(o=>o.v===tooth.crown)?.l}</span>
                      </div>
                    )}
                  </div>
                )}
              </>
            )}
          </OdoSection>
        </div>

        {/* Çürük */}
        <div style={SC.card}>
          <OdoSection title="Çürük" open={openSections.caries} onToggle={() => toggle('caries')}>
            {!tooth && !multi ? <p style={{fontSize:12,color:'var(--text-mute)',margin:0}}>Bir diş seçin.</p> : (
              <>
                <p style={{fontSize:11,color:'var(--text-mute)',margin:'0 0 6px'}}>Çürük yüzey seçin</p>
                <SurfBtns surfaces={['O','B','L','M','D']} activeArr={tooth?.caries || []} onChange={s => toggleSurf('caries', s)}/>
              </>
            )}
          </OdoSection>
        </div>

        {/* Dolgu */}
        <div style={SC.card}>
          <OdoSection title="Dolgu ve Restorasyon" open={openSections.fill} onToggle={() => toggle('fill')}>
            {!tooth && !multi ? <p style={{fontSize:12,color:'var(--text-mute)',margin:0}}>Bir diş seçin.</p> : (
              <>
                <label style={CS.label}>Dolgu Türü</label>
                <select value={tooth?.filling || 'none'} onChange={e => upd('filling', e.target.value)} style={{...SEL,marginBottom:8}}>
                  {_FILL_OPTS.map(o => <option key={o.v} value={o.v}>{o.l}</option>)}
                </select>
                {tooth?.filling && tooth.filling !== 'none' && (
                  <>
                    <label style={CS.label}>Dolgu Yüzeyleri</label>
                    <SurfBtns surfaces={['O','B','L','M','D']} activeArr={tooth?.fillingSurfaces || []} onChange={s => toggleSurf('fillingSurfaces', s)}/>
                  </>
                )}
              </>
            )}
          </OdoSection>
        </div>

        {/* Kök */}
        <div style={SC.card}>
          <OdoSection title="Kök" open={openSections.root} onToggle={() => toggle('root')}>
            {!tooth && !multi ? <p style={{fontSize:12,color:'var(--text-mute)',margin:0}}>Bir diş seçin.</p> : (
              <select value={tooth?.root || 'healthy'} onChange={e => upd('root', e.target.value)} style={SEL}>
                {_ROOT_OPTS.map(o => <option key={o.v} value={o.v}>{o.l}</option>)}
              </select>
            )}
          </OdoSection>
        </div>

        {/* Periodontoloji */}
        <div style={SC.card}>
          <OdoSection title="Periodontoloji ve Diğer" open={openSections.other} onToggle={() => toggle('other')}>
            {!tooth && !multi ? <p style={{fontSize:12,color:'var(--text-mute)',margin:0}}>Bir diş seçin.</p> : (
              <>
                <div style={{marginBottom:10}}>
                  <label style={CS.label}>Mobilite</label>
                  <select value={tooth?.mobility || '0'} onChange={e => upd('mobility', e.target.value)} style={SEL}>
                    {_MOB_OPTS.map(o => <option key={o.v} value={o.v}>{o.l}</option>)}
                  </select>
                </div>
                {[{k:'fissureSealing',l:'Fissür Sealant'},{k:'pulpInflam',l:'Pulpa İltihap'},{k:'bruxism',l:'Bruksizm Aşınması'}].map(item => (
                  <div key={item.k} style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:8}}>
                    <span style={{fontSize:12,color:'var(--text)'}}>{item.l}</span>
                    <button type="button" onClick={() => upd(item.k, !(tooth?.[item.k]))}
                      className={`toggle-btn ${tooth?.[item.k] ? 'is-on' : ''}`}>
                      <span className="toggle-thumb"/>
                    </button>
                  </div>
                ))}
              </>
            )}
          </OdoSection>
        </div>

        {/* Legend */}
        <div style={{...SC.card,maxWidth:280}}>
          <div style={{padding:'10px 12px',background:'var(--surface)',borderRadius:10,border:'1px solid var(--line)'}}>
            <div style={{fontSize:10,fontWeight:700,color:'var(--text-mute)',marginBottom:6,textTransform:'uppercase',letterSpacing:.5}}>Renk Göstergesi</div>
            <div style={{display:'flex',flexWrap:'wrap',gap:6}}>
              {[
                {c:'#ef4444',l:'Çürük'},{c:'#3b82f6',l:'Kompozit'},{c:'#64748b',l:'Amalgam'},
                {c:'#a78bfa',l:'Seramik'},{c:'#f59e0b',l:'Tam Kron'},{c:'#2B47E8',l:'Zirkonyum/İmplant'},
                {c:'#8b5cf6',l:'PFM/Locator'},{c:'#10b981',l:'Fissür'},
              ].map(i => (
                <span key={i.l} style={{display:'flex',alignItems:'center',gap:3,fontSize:10,color:'var(--text-mute)'}}>
                  <span style={{width:8,height:8,borderRadius:'50%',background:i.c,display:'inline-block',flexShrink:0}}/>{i.l}
                </span>
              ))}
            </div>
          </div>
        </div>

      </div>
    </div>
  );
}

// ── Modal ─────────────────────────────────────────────────────────
function OdontogramModal({ patient, onUpdate, onClose }) {
  const initTeeth = () => {
    const saved = patient.odontogram || {};
    const res = {};
    _ALL.forEach(n => { res[n] = {..._odoDefault(), ...(saved[String(n)] || {})}; });
    return res;
  };

  const [teeth, setTeeth] = React.useState(initTeeth);
  const [selected, setSelected] = React.useState([]);

  React.useEffect(() => {
    const h = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', h);
    return () => document.removeEventListener('keydown', h);
  }, [onClose]);

  const handleSelect = (num, e) => {
    if (e.ctrlKey || e.metaKey) {
      setSelected(prev => prev.includes(num) ? prev.filter(n => n !== num) : [...prev, num]);
    } else {
      setSelected(prev => prev.length === 1 && prev[0] === num ? [] : [num]);
    }
  };

  const handleUpdateTooth = (nums, key, value, surfToggle) => {
    setTeeth(prev => {
      const next = {...prev};
      nums.forEach(n => {
        const t = {...(next[n] || _odoDefault())};
        if (surfToggle !== undefined) {
          const arr = [...(t[key] || [])];
          const idx = arr.indexOf(surfToggle);
          if (idx >= 0) arr.splice(idx, 1); else arr.push(surfToggle);
          t[key] = arr;
        } else { t[key] = value; }
        next[n] = t;
      });
      return next;
    });
  };

  const handleApplyGroup = (action) => {
    setTeeth(prev => {
      const next = {...prev};
      if (action === 'reset') { _ALL.forEach(n => { next[n] = _odoDefault(); }); }
      else if (action === 'milk') { _ALL.forEach(n => { next[n] = {...(next[n]||_odoDefault()), base:'milk'}; }); }
      else if (action === 'mixed') {
        _UPPER.forEach(n => { next[n] = {...(next[n]||_odoDefault()), base:'permanent'}; });
        _LOWER.forEach(n => { next[n] = {...(next[n]||_odoDefault()), base:'milk'}; });
      } else if (action === 'edentulous') { _ALL.forEach(n => { next[n] = {...(next[n]||_odoDefault()), base:'missing'}; }); }
      return next;
    });
  };

  const handleSave = () => {
    const out = {};
    Object.entries(teeth).forEach(([k, v]) => { out[k] = v; });
    const note = _buildNote(patient.odontogram || {}, teeth);
    const notes = (patient.notes || '') + (note || ('\n[' + new Date().toLocaleDateString('tr-TR',{day:'2-digit',month:'2-digit',year:'numeric'}) + '] Odontogram görüntülendi.'));
    onUpdate({ odontogram: out, notes });
    onClose();
  };

  const renderRow = (leftTeeth, rightTeeth, isUpper) => (
    <div className={`odont-row${isUpper ? ' odont-row--upper' : ' odont-row--lower'}`}>
      {leftTeeth.map(num => (
        <OdoToothCell key={num} num={num} tooth={teeth[num] || _odoDefault()}
          selected={selected.includes(num)} onSelect={(e) => handleSelect(num, e)}/>
      ))}
      <div className="odont-midline"/>
      {rightTeeth.map(num => (
        <OdoToothCell key={num} num={num} tooth={teeth[num] || _odoDefault()}
          selected={selected.includes(num)} onSelect={(e) => handleSelect(num, e)}/>
      ))}
    </div>
  );

  return (
    <div className="odont-modal-overlay" onClick={(e) => e.target === e.currentTarget && onClose()}>
      <div className="odont-modal" style={{maxWidth:'min(1300px,97vw)',width:'min(1300px,97vw)',display:'flex',flexDirection:'column',maxHeight:'95vh'}}>
        <div className="odont-modal-head" style={{flexShrink:0}}>
          <div style={{display:'flex',alignItems:'baseline',gap:10}}>
            <span className="odont-modal-title">Dental Harita</span>
            <span style={{fontSize:13,color:'var(--text-mute)',fontWeight:500}}>{patient.name}</span>
          </div>
          <div style={{display:'flex',gap:8,alignItems:'center'}}>
            <span style={{fontSize:11,color:'var(--text-mute)'}}>Ctrl+click çoklu seçim</span>
            <button className="btn btn--accent btn--sm" onClick={handleSave}>Kaydet</button>
            <button className="icon-btn" onClick={onClose} title="Kapat (Esc)">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round">
                <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
              </svg>
            </button>
          </div>
        </div>
        <div style={{flex:1,overflowY:'auto'}}>
          <div className="odont-modal-body" style={{overflowX:'auto',padding:'16px 12px'}}>
            <div style={{width:'max-content',margin:'0 auto'}}>
              <div className="odont-jaw-label">Üst Çene</div>
              {renderRow(_UR, _UL, true)}
              <div style={{height:20}}/>
              <div className="odont-jaw-label">Alt Çene</div>
              {renderRow(_LR, _LL, false)}
            </div>
          </div>
          <OdoControls teeth={teeth} selected={selected} onSetSelected={setSelected}
            onUpdateTooth={handleUpdateTooth} onApplyGroup={handleApplyGroup}/>
        </div>
      </div>
    </div>
  );
}

// ── Inline chart (desktop split panel) ───────────────────────────
function OdontogramChart({ patient, onUpdate }) {
  const initTeeth = () => {
    const saved = patient.odontogram || {};
    const res = {};
    _ALL.forEach(n => { res[n] = {..._odoDefault(), ...(saved[String(n)] || {})}; });
    return res;
  };

  const [teeth, setTeeth] = React.useState(initTeeth);
  const [selected, setSelected] = React.useState([]);

  const handleSelect = (num, e) => {
    if (e.ctrlKey || e.metaKey) {
      setSelected(prev => prev.includes(num) ? prev.filter(n => n !== num) : [...prev, num]);
    } else {
      setSelected(prev => prev.length === 1 && prev[0] === num ? [] : [num]);
    }
  };

  const handleUpdateTooth = (nums, key, value, surfToggle) => {
    setTeeth(prev => {
      const next = {...prev};
      nums.forEach(n => {
        const t = {...(next[n] || _odoDefault())};
        if (surfToggle !== undefined) {
          const arr = [...(t[key] || [])];
          const idx = arr.indexOf(surfToggle);
          if (idx >= 0) arr.splice(idx, 1); else arr.push(surfToggle);
          t[key] = arr;
        } else { t[key] = value; }
        next[n] = t;
      });
      return next;
    });
  };

  const handleApplyGroup = (action) => {
    setTeeth(prev => {
      const next = {...prev};
      if (action === 'reset') { _ALL.forEach(n => { next[n] = _odoDefault(); }); }
      else if (action === 'milk') { _ALL.forEach(n => { next[n] = {...(next[n]||_odoDefault()), base:'milk'}; }); }
      else if (action === 'mixed') {
        _UPPER.forEach(n => { next[n] = {...(next[n]||_odoDefault()), base:'permanent'}; });
        _LOWER.forEach(n => { next[n] = {...(next[n]||_odoDefault()), base:'milk'}; });
      } else if (action === 'edentulous') { _ALL.forEach(n => { next[n] = {...(next[n]||_odoDefault()), base:'missing'}; }); }
      return next;
    });
  };

  const handleSave = () => {
    const out = {};
    Object.entries(teeth).forEach(([k, v]) => { out[k] = v; });
    const note = _buildNote(patient.odontogram || {}, teeth);
    const notes = (patient.notes || '') + (note || ('\n[' + new Date().toLocaleDateString('tr-TR',{day:'2-digit',month:'2-digit',year:'numeric'}) + '] Odontogram görüntülendi.'));
    onUpdate({ odontogram: out, notes });
  };

  const renderRow = (leftTeeth, rightTeeth, isUpper) => (
    <div className={`odont-row${isUpper ? ' odont-row--upper' : ' odont-row--lower'}`}>
      {leftTeeth.map(num => (
        <OdoToothCell key={num} num={num} tooth={teeth[num] || _odoDefault()}
          selected={selected.includes(num)} onSelect={(e) => handleSelect(num, e)}/>
      ))}
      <div className="odont-midline"/>
      {rightTeeth.map(num => (
        <OdoToothCell key={num} num={num} tooth={teeth[num] || _odoDefault()}
          selected={selected.includes(num)} onSelect={(e) => handleSelect(num, e)}/>
      ))}
    </div>
  );

  return (
    <div style={{height:'100%',overflowY:'auto'}}>
      <div style={{overflowX:'auto',padding:'12px'}}>
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:10}}>
          <span style={{fontSize:11,color:'var(--text-mute)'}}>Ctrl+click çoklu seçim</span>
          <button className="btn btn--accent btn--sm" onClick={handleSave}>Kaydet</button>
        </div>
        <div style={{width:'max-content',margin:'0 auto'}}>
          <div className="odont-jaw-label">Üst Çene</div>
          {renderRow(_UR, _UL, true)}
          <div style={{height:20}}/>
          <div className="odont-jaw-label">Alt Çene</div>
          {renderRow(_LR, _LL, false)}
        </div>
      </div>
      <OdoControls teeth={teeth} selected={selected} onSetSelected={setSelected}
        onUpdateTooth={handleUpdateTooth} onApplyGroup={handleApplyGroup}/>
    </div>
  );
}

function OdontogramTab({ patient, onUpdate }) {
  return (
    <div style={{padding:'24px',textAlign:'center'}}>
      <p style={{fontSize:13,color:'var(--text-mute)',marginBottom:12}}>Dental harita modal olarak açılır.</p>
    </div>
  );
}
