const { useState, useEffect, useRef, useCallback, useMemo } = React;

function CopyButton({text}){const[c,setC]=useState(false);const copy=()=>{navigator.clipboard.writeText(text).then(()=>{setC(true);setTimeout(()=>setC(false),1800);});};
  return(<button onClick={copy} className="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-all hover:bg-gray-100 border border-gray-200">
    {c?(<><svg className="w-3.5 h-3.5 text-emerald-500 animate-check" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M5 13l4 4L19 7"/></svg><span className="text-emerald-600">Copied</span></>):
    (<><svg className="w-3.5 h-3.5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="9" y="9" width="13" height="13" rx="2" ry="2" strokeWidth={1.5}/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1" strokeWidth={1.5}/></svg><span className="text-gray-500">Copy</span></>)}</button>);}

function CompatBadges({compat}){const i={excel:{l:'Excel',c:'#217346'},sheets:{l:'Sheets',c:'#0F9D58'},libre:{l:'Libre',c:'#18A303'}};
  return(<div className="flex gap-1.5">{(compat||[]).map(k=>(<span key={k} className="text-[10px] font-semibold px-1.5 py-0.5 rounded" style={{background:i[k]?.c+'18',color:i[k]?.c}}>{i[k]?.l}</span>))}</div>);}

function TreeBlock({node,depth=0,hoveredId,setHoveredId,idPrefix='0'}){
  if(!node)return null;const isF=!!node.fn;const cat=CAT[node.cat]||CAT.value;const nid=idPrefix;
  const isH=hoveredId===nid;const isD=hoveredId&&hoveredId!==nid&&!nid.startsWith(hoveredId)&&!hoveredId.startsWith(nid);
  if(!isF)return(<div className={`tree-block px-3 py-2 border-l-[3px] animate-fade-in-up ${isD?'block-dim':'block-normal'} ${isH?'block-glow':''}`}
    style={{borderLeftColor:cat.border,background:cat.bg+'80',animationDelay:depth*60+'ms'}}
    onMouseEnter={()=>setHoveredId(nid)} onMouseLeave={()=>setHoveredId(null)}>
    <div className="flex items-center gap-2 flex-wrap"><span className="text-[0.65rem] px-1.5 py-px rounded-full font-semibold uppercase tracking-wide" style={{background:cat.pill+'22',color:cat.text}}>{CAT[node.cat]?.label||'Value'}</span>
      <code className="font-mono text-sm font-medium" style={{color:cat.text}}>{node.val}</code></div>
    {node.label&&node.label!==node.val&&<div className="text-xs text-gray-500 mt-1">{node.label}</div>}
    {node.detail&&<div className="text-xs text-gray-500 mt-1.5 leading-relaxed">{node.detail}</div>}</div>);
  return(<div className={`tree-block border rounded-lg overflow-hidden animate-fade-in-up ${isD?'block-dim':'block-normal'} ${isH?'block-glow':''}`}
    style={{borderColor:cat.border+'80',background:cat.bg+'40',animationDelay:depth*60+'ms'}}
    onMouseEnter={e=>{e.stopPropagation();setHoveredId(nid);}} onMouseLeave={e=>{e.stopPropagation();setHoveredId(null);}}>
    <div className="flex items-center gap-2 px-3 py-2" style={{background:cat.bg}}>
      <span className="font-mono font-semibold text-sm" style={{color:cat.text}}>{node.fn}</span>
      <span className="text-xs" style={{color:cat.text+'CC'}}>{node.label}</span></div>
    <div className="flex flex-col gap-1.5 p-2">{(node.args||[]).map((a,i)=>(<TreeBlock key={i} node={a} depth={depth+1} hoveredId={hoveredId} setHoveredId={setHoveredId} idPrefix={nid+'-'+i}/>))}</div></div>);}

function FormulaBar({formula,compat}){const[t,setT]=useState('');const[d,setD]=useState(false);
  useEffect(()=>{setT('');setD(false);let i=0;const iv=setInterval(()=>{i++;if(i<=formula.length)setT(formula.slice(0,i));else{setD(true);clearInterval(iv);}},18);return()=>clearInterval(iv);},[formula]);
  return(<div className="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden">
    <div className="flex items-center justify-between px-4 py-2 border-b border-gray-100 bg-gray-50/50">
      <span className="text-xs font-semibold text-gray-400 uppercase tracking-wide">Formula</span>
      <div className="flex items-center gap-3"><CompatBadges compat={compat}/><CopyButton text={formula}/></div></div>
    <div className="px-4 py-3 overflow-x-auto"><code className="font-mono text-sm md:text-base font-medium text-navy leading-relaxed whitespace-pre-wrap break-all">
      {t}{!d&&<span className="inline-block w-[2px] h-[1em] bg-navy ml-[1px] align-middle" style={{animation:'blink 0.8s step-end infinite'}}/>}</code></div></div>);}

function FormulaResult({formula,tree,tips,summary,compat}){const[hov,setHov]=useState(null);
  return(<div className="space-y-4 animate-fade-in-up">
    <FormulaBar formula={formula} compat={compat||['excel','sheets']}/>
    {summary&&(<div className="px-4 py-3 bg-white rounded-xl border border-gray-200 shadow-sm animate-fade-in" style={{animationDelay:'150ms'}}>
      <h4 className="text-xs font-semibold text-gray-400 uppercase tracking-wide mb-1.5">What it does</h4>
      <p className="text-sm text-gray-700 leading-relaxed">{summary}</p></div>)}
    <div className="animate-fade-in" style={{animationDelay:'200ms'}}>
      <h4 className="text-xs font-semibold text-gray-400 uppercase tracking-wide mb-3">Visual Breakdown</h4>
      <TreeBlock node={tree} hoveredId={hov} setHoveredId={setHov}/></div>
    {tips&&tips.length>0&&(<div className="mt-4 animate-fade-in" style={{animationDelay:'300ms'}}>
      <h4 className="text-xs font-semibold text-gray-400 uppercase tracking-wide mb-2">Tips & Gotchas</h4>
      <ul className="space-y-1.5">{tips.map((t,i)=>(<li key={i} className="flex gap-2 text-sm text-gray-600"><span className="text-amber-500 mt-0.5 flex-shrink-0">{'\u26A0'}</span><span>{t}</span></li>))}</ul></div>)}</div>);}

function NutshellItem({formula:f,isOpen,onToggle}){const ref=useRef(null);const[h,setH]=useState(0);
  useEffect(()=>{if(ref.current)setH(ref.current.scrollHeight);});
  const cols={aging:CAT.logic,lookup:CAT.lookup,totals:CAT.math,dates:CAT.date,finance:CAT.financial,cleanup:CAT.text,errors:CAT.error,combos:CAT.reference,validation:CAT.lookup,recon:CAT.comparison,arrays:CAT.reference,tax:CAT.financial,running:CAT.math,payroll:CAT.date,dupes:CAT.error,periods:CAT.comparison,format:CAT.text,rounding:CAT.financial,bankrec:CAT.lookup};
  const accent=cols[f.cat]||CAT.value;
  return(<div className={`border-b border-gray-100 ${isOpen?'bg-white':''}`}>
    <button onClick={onToggle} className={`nutshell-trigger-btn w-full flex items-center gap-3 px-4 py-3.5 text-left border-l-[3px] transition-all ${isOpen?'border-l-[3px]':'border-l-transparent hover:border-l-[3px]'}`}
      style={{borderLeftColor:isOpen?accent.border:undefined}} onMouseEnter={e=>{if(!isOpen)e.currentTarget.style.borderLeftColor=accent.border;}} onMouseLeave={e=>{if(!isOpen)e.currentTarget.style.borderLeftColor='transparent';}}>
      <svg className={`w-4 h-4 text-gray-400 flex-shrink-0 nutshell-arrow ${isOpen?'open':''}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7"/></svg>
      <div className="min-w-0 flex-1"><div className="flex items-center gap-2 flex-wrap">
        <span className="text-sm font-semibold text-gray-800">{f.name}</span><CompatBadges compat={f.compat}/></div>
        <div className="text-xs text-gray-400 mt-0.5 leading-snug truncate">{f.desc}</div></div></button>
    <div className="nutshell-expand overflow-hidden" style={{maxHeight:isOpen?(h+40)+'px':'0px',opacity:isOpen?1:0}}>
      <div ref={ref} className="px-4 pb-5 pt-1 ml-7">{isOpen&&<FormulaResult formula={f.formula} tree={f.tree} tips={f.tips} summary={f.summary} compat={f.compat}/>}</div></div></div>);}

const PLACEHOLDERS=["Sum all invoices from Q3 over $1,000","Flag invoices more than 30 days past due","Look up a client from another sheet","Calculate monthly loan payment","What percentage of invoices are overdue?","Create an interactive dropdown report","Calculate straight-line depreciation","Find a partial match with wildcards"];

function App(){
  const[mode,setMode]=useState('describe');const[query,setQuery]=useState('');const[result,setResult]=useState(null);
  const[activeCat,setActiveCat]=useState('all');const[openId,setOpenId]=useState(null);
  const[phIdx,setPhIdx]=useState(0);const[libSearch,setLibSearch]=useState('');const inputRef=useRef(null);

  useEffect(()=>{const iv=setInterval(()=>setPhIdx(i=>(i+1)%PLACEHOLDERS.length),3500);return()=>clearInterval(iv);},[]);

  const filtered=useMemo(()=>{let list=FORMULAS;
    if(activeCat!=='all')list=list.filter(f=>f.cat===activeCat);
    if(libSearch.trim()){const q=libSearch.toLowerCase();list=list.filter(f=>f.name.toLowerCase().includes(q)||f.desc.toLowerCase().includes(q)||f.formula.toLowerCase().includes(q));}
    return list;},[activeCat,libSearch]);

  const handleSubmit=useCallback((q,fm)=>{const input=q||query;if(!input.trim())return;const m=fm||mode;
    if(m==='paste'||(input.trim().startsWith('=')&&m==='describe')){
      const tree=parseFormula(input);setResult({formula:input.trim(),tree,summary:generateSummary(tree),tips:null,compat:['excel','sheets'],isParsed:true});
    }else{const matches=matchFormulas(input);
      if(matches.length>0){const b=matches[0];setResult({formula:b.formula,tree:b.tree,summary:b.summary,tips:b.tips,compat:b.compat,matchName:b.name});}
      else setResult({noMatch:true});}setOpenId(null);},[query,mode]);

  return(<div className="min-h-screen flex flex-col">
    <header className="sticky top-0 z-20 bg-white/90 backdrop-blur-sm border-b border-gray-100">
      <div className="max-w-4xl mx-auto px-4 md:px-8 py-4 flex items-center justify-between">
        <h1 className="font-display text-xl md:text-2xl text-navy">Formula Translator</h1>
        <div className="flex items-center bg-gray-100 rounded-lg p-0.5">
          <button onClick={()=>setMode('describe')} className={`px-3 py-1.5 text-xs font-semibold rounded-md transition-all ${mode==='describe'?'bg-white text-navy shadow-sm':'text-gray-500 hover:text-gray-700'}`}>{'Describe \u2192 Generate'}</button>
          <button onClick={()=>setMode('paste')} className={`px-3 py-1.5 text-xs font-semibold rounded-md transition-all ${mode==='paste'?'bg-white text-navy shadow-sm':'text-gray-500 hover:text-gray-700'}`}>{'Paste \u2192 Explain'}</button></div></div></header>
    <main className="flex-1 overflow-y-auto main-scroll"><div className="max-w-4xl mx-auto px-4 md:px-8 py-6">
      <div className="relative">
        <input ref={inputRef} type="text" value={query} onChange={e=>setQuery(e.target.value)} onKeyDown={e=>{if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();handleSubmit();}}}
          placeholder={mode==='paste'?'Paste a formula here (e.g., =VLOOKUP(A2,Sheet2!A:B,2,FALSE))':PLACEHOLDERS[phIdx]}
          className="w-full px-5 py-4 text-base md:text-lg bg-white border-2 border-gray-200 rounded-xl shadow-sm focus:outline-none focus:ring-4 focus:ring-navy/10 focus:border-navy/40 transition-all pr-28 font-body"/>
        <button onClick={()=>handleSubmit()} className="absolute right-2 top-1/2 -translate-y-1/2 px-4 py-2 bg-navy text-white text-sm font-semibold rounded-lg hover:bg-navy/90 transition-all shadow-sm hover:shadow active:scale-[0.97]">
          {mode==='paste'?'Explain':'Generate'}</button></div>

      {result&&!result.noMatch&&(<div className="mt-6" key={result.formula}>
        <div className="flex items-center justify-between mb-3">
          <div className="flex items-center gap-2 text-xs text-gray-400 animate-fade-in">
            <span className={`inline-block w-1.5 h-1.5 rounded-full ${result.isParsed?'bg-blue-400':'bg-emerald-400'}`}></span>
            {result.isParsed?'Parsed formula':<>{'Matched: '}<span className="font-semibold text-gray-600">{result.matchName}</span></>}</div>
          <button onClick={()=>{setResult(null);setQuery('');}} className="text-xs text-gray-400 hover:text-gray-600 transition">{'\u2715 Clear'}</button></div>
        <FormulaResult formula={result.formula} tree={result.tree} tips={result.tips} summary={result.summary} compat={result.compat}/></div>)}

      {result?.noMatch&&(<div className="mt-6 p-6 bg-white rounded-xl border border-gray-200 shadow-sm text-center animate-fade-in-up">
        <p className="text-gray-700 font-medium mb-1">No matching formula found</p>
        <p className="text-sm text-gray-400">Try different keywords, or browse the library below.</p></div>)}

      <div className="mt-8 mb-4">
        <div className="flex items-center justify-between mb-4">
          <h2 className="font-display text-lg text-navy">Formula Library <span className="text-sm font-body font-normal text-gray-400 ml-1">({FORMULAS.length})</span></h2>
          <input type="text" value={libSearch} onChange={e=>setLibSearch(e.target.value)} placeholder="Filter..."
            className="w-40 px-3 py-1.5 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-navy/20 bg-gray-50"/></div>
        <div className="flex flex-wrap gap-2 mb-4">{CATEGORIES.map(c=>(
          <button key={c.id} onClick={()=>setActiveCat(c.id)} className={`category-pill ${activeCat===c.id?'active':''}`}
            style={{color:activeCat===c.id?'#1B2A4A':'#6B7280',background:activeCat===c.id?'#1B2A4A10':'transparent',borderColor:activeCat===c.id?'#1B2A4A40':'transparent'}}>
            {c.icon&&<span className="mr-1">{c.icon}</span>}{c.name}
            {c.id!=='all'&&<span className="ml-1 opacity-50">({FORMULAS.filter(f=>f.cat===c.id).length})</span>}</button>))}</div>
        <div className="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden">
          {filtered.length===0?(<div className="px-4 py-8 text-center text-sm text-gray-400">No formulas match.</div>):
          filtered.map(f=>(<NutshellItem key={f.id} formula={f} isOpen={openId===f.id} onToggle={()=>setOpenId(openId===f.id?null:f.id)}/>))}</div></div>
    </div></main>
    <footer className="px-4 py-3 border-t border-gray-100 bg-white/80 text-center">
      <p className="text-xs text-gray-300">{'Built with Claude \u2014 this entire app was created in a single conversation'}</p></footer></div>);}

ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
