const CS_PALETTE = [['Teal','#61bdb7'],['Deep teal','#108474'],['Navy','#242253'],['Gold','#fdbd32'],['Pink','#f082b4'],['Ink','#3e4761'],['Black','#1c1d1d'],['White','#ffffff'],['Red','#C20000']];
const CS_FONTS = ['Poppins','Tilt Warp','Tomarik Poster','Tomarik Brush'];
const CS_SHAPES = [
  { shape:'rect', name:'Square' }, { shape:'rounded', name:'Rounded' }, { shape:'circle', name:'Circle' },
  { shape:'triangle', name:'Triangle' }, { shape:'line', name:'Line' }
];
function Swatch({ color, active, onClick, size = 22 }) {
  return <button title={color} onClick={onClick} style={{width:size,height:size,borderRadius:6,cursor:'pointer',padding:0,
    background:color,border:color==='#ffffff'?'1px solid var(--sitm-border)':'1px solid rgba(0,0,0,.08)',
    outline:active?'2px solid var(--sitm-teal)':'none',outlineOffset:2,flex:'none'}}></button>;
}
function shapeStyle(o) {
  const base = { width:'100%', height:'100%', opacity:1 };
  const fill = o.gradient ? 'linear-gradient(135deg, '+o.fill+', '+(o.fill2||'#ffffff')+')' : o.fill;
  if (o.shape==='circle') return {...base, background:fill, borderRadius:'50%'};
  if (o.shape==='rounded') return {...base, background:fill, borderRadius:14};
  if (o.shape==='triangle') return {...base, background:fill, clipPath:'polygon(50% 0, 100% 100%, 0 100%)'};
  if (o.shape==='line') return {...base, background:fill, borderRadius:99};
  return {...base, background:fill};
}
function ObjectBody({ o, editing, onCommit }) {
  if (o.type==='shape') return <div style={shapeStyle(o)}></div>;
  if (o.type==='element') return <ElementArt kind={o.kind} w={o.w} h={o.h}/>;
  if (o.type==='text') return <div contentEditable={!!editing} suppressContentEditableWarning className={editing?'cs-edit':''}
    onBlur={(e)=>onCommit && onCommit(e.currentTarget.innerText)}
    style={{width:'100%',minHeight:'100%',fontFamily:"'"+o.font+"'",fontSize:o.size,color:o.color,fontWeight:o.bold?700:o.font==='Poppins'?400:'normal',
      fontStyle:o.italic?'italic':'normal',textDecoration:o.underline?'underline':'none',lineHeight:1.3,textAlign:o.align||'left',outlineOffset:0,
      cursor:editing?'text':'inherit',userSelect:editing?'text':'none'}}>{o.text}</div>;
  return null;
}
const HANDLES = [
  ['nw',0,0,'nwse-resize'],['n',0.5,0,'ns-resize'],['ne',1,0,'nesw-resize'],['e',1,0.5,'ew-resize'],
  ['se',1,1,'nwse-resize'],['s',0.5,1,'ns-resize'],['sw',0,1,'nesw-resize'],['w',0,0.5,'ew-resize']
];
function CanvasObject({ o, selected, editing, onSelect, onChange, onEdit }) {
  const [hov,setHov] = React.useState(false);
  const ref = React.useRef(null);
  const dragBody = (e) => {
    if (o.type==='text' && editing) { e.stopPropagation(); return; } // native text interaction while editing
    e.preventDefault(); e.stopPropagation();
    const wasSelected = selected;
    onSelect(o.id);
    const sx = e.clientX - o.x, sy = e.clientY - o.y, ux = e.clientX, uy = e.clientY;
    let moved = false;
    const mm = (ev)=>{ if (Math.abs(ev.clientX-ux)+Math.abs(ev.clientY-uy) > 3) moved = true; if (moved) onChange(o.id, { x: ev.clientX - sx, y: ev.clientY - sy }); };
    const up = (ev)=>{ window.removeEventListener('mousemove',mm); window.removeEventListener('mouseup',up);
      if (!moved && wasSelected && o.type==='text' && onEdit) { onEdit(o.id);
        setTimeout(()=>{ const el = ref.current && ref.current.firstChild; if (!el) return; el.focus();
          try { const r = document.caretRangeFromPoint ? document.caretRangeFromPoint(ev.clientX, ev.clientY)
            : (document.caretPositionFromPoint ? (()=>{ const p = document.caretPositionFromPoint(ev.clientX, ev.clientY); const rr = document.createRange(); rr.setStart(p.offsetNode, p.offset); return rr; })() : null);
            if (r) { const s = window.getSelection(); s.removeAllRanges(); s.addRange(r); } } catch(err){}
        }, 30);
      } };
    window.addEventListener('mousemove',mm); window.addEventListener('mouseup',up);
  };
  const dragHandle = (h) => (e) => {
    e.preventDefault(); e.stopPropagation();
    const [pos,fx,fy] = h; const start = {x:e.clientX,y:e.clientY,ox:o.x,oy:o.y,ow:o.w,oh:o.h};
    const mm = (ev)=>{
      const dx = ev.clientX-start.x, dy = ev.clientY-start.y;
      let x=start.ox,y=start.oy,w=start.ow,h2=start.oh;
      if (pos.includes('e')) w = Math.max(24, start.ow+dx);
      if (pos.includes('s')) h2 = Math.max(16, start.oh+dy);
      if (pos.includes('w')) { w = Math.max(24, start.ow-dx); x = start.ox + (start.ow-w); }
      if (pos.includes('n')) { h2 = Math.max(16, start.oh-dy); y = start.oy + (start.oh-h2); }
      onChange(o.id,{x,y,w,h:h2});
    };
    const up = ()=>{ window.removeEventListener('mousemove',mm); window.removeEventListener('mouseup',up); };
    window.addEventListener('mousemove',mm); window.addEventListener('mouseup',up);
  };
  return <div ref={ref} onMouseDown={dragBody} onClick={(e)=>{e.stopPropagation();}} onMouseEnter={()=>setHov(true)} onMouseLeave={()=>setHov(false)}
    style={{position:'absolute',left:o.x,top:o.y,width:o.w,height:o.h,zIndex:10+o.z,opacity:(o.opacity!=null?o.opacity:100)/100,
      cursor:editing?'text':'grab',outline:selected?'2px solid var(--sitm-teal)':hov?'1.5px dashed var(--sitm-teal)':'none',outlineOffset:1}}>
    <ObjectBody o={o} editing={editing} onCommit={(t)=>onChange(o.id,{text:t})}/>
    {selected && HANDLES.map(h=><div key={h[0]} onMouseDown={dragHandle(h)}
      style={{position:'absolute',left:'calc('+(h[1]*100)+'% - 5px)',top:'calc('+(h[2]*100)+'% - 5px)',width:10,height:10,background:'#fff',
        border:'1.5px solid var(--sitm-teal)',borderRadius:3,cursor:h[3],zIndex:5}}></div>)}
  </div>;
}
function TinyBtn({ icon, label, onClick, active, danger }) {
  const [h,setH] = React.useState(false);
  return <button title={label} onClick={onClick} onMouseEnter={()=>setH(true)} onMouseLeave={()=>setH(false)}
    style={{display:'inline-flex',alignItems:'center',gap:6,fontFamily:'var(--sitm-font-body)',fontSize:12,fontWeight:600,padding:'6px 9px',cursor:'pointer',borderRadius:7,
      border:'1px solid '+(active?'var(--sitm-teal)':danger&&h?'var(--sitm-sale-text)':'var(--sitm-border)'),
      background:active?'rgba(97,189,183,.15)':h?(danger?'rgba(194,0,0,.06)':'var(--sitm-text-a05)'):'#fff',
      color:danger&&h?'var(--sitm-sale-text)':active?'var(--sitm-teal-deep)':'var(--sitm-text)'}}>
    {icon && <Icon name={icon} size={13}/>}{label}
  </button>;
}
function ToolSep(){ return <span style={{width:1,height:22,background:'var(--sitm-border)',margin:'0 4px',flex:'none'}}></span>; }
function OpacityCtl({ value, onChange }) {
  return <span style={{display:'inline-flex',alignItems:'center',gap:7,fontSize:11.5,color:'var(--sitm-text)'}}>
    Opacity<input type="range" min="10" max="100" value={value!=null?value:100} onChange={e=>onChange(parseInt(e.target.value))} style={{width:80,accentColor:'var(--sitm-teal)'}}/>
  </span>;
}
// contextual toolbar under the top bar
function SelectionToolbar({ sel, onChange, onLayer, onDuplicate, onDelete, hasTextSel, execText }) {
  const wrap = { background:'#fff',borderBottom:'1px solid var(--sitm-border)',padding:'7px 24px',display:'flex',alignItems:'center',gap:8,minHeight:44,boxSizing:'border-box',flexWrap:'wrap' };
  if (!sel && hasTextSel) return <div style={wrap}>
    <span style={{fontSize:11.5,fontWeight:600,color:'var(--sitm-teal-deep)',textTransform:'uppercase',letterSpacing:'0.06em',marginRight:4}}>Text</span>
    <span style={{position:'relative',display:'inline-block',width:130}}>
      <select onChange={e=>execText('fontName',e.target.value)} defaultValue="Poppins" style={{width:'100%',appearance:'none',WebkitAppearance:'none',fontFamily:'var(--sitm-font-body)',fontSize:12,fontWeight:500,padding:'6px 24px 6px 10px',background:'#fff',border:'1px solid var(--sitm-border)',borderRadius:7,cursor:'pointer',color:'var(--sitm-text)'}}>
        {CS_FONTS.map(f=><option key={f} value={f}>{f}</option>)}
      </select>
      <span style={{position:'absolute',right:8,top:'50%',transform:'translateY(-50%)',pointerEvents:'none',color:'var(--sitm-text)'}}><Icon name="chevR" size={11} style={{transform:'rotate(90deg)'}}/></span>
    </span>
    {[['1','S'],['3','M'],['5','L'],['7','XL']].map(([v,l])=><TinyBtn key={v} label={l} onClick={()=>execText('fontSize',v)}/>)}
    <ToolSep/>
    <TinyBtn label="B" onClick={()=>execText('bold')}/>
    <TinyBtn label="I" onClick={()=>execText('italic')}/>
    <TinyBtn label="U" onClick={()=>execText('underline')}/>
    <ToolSep/>
    {CS_PALETTE.map(([n,c])=><Swatch key={c} color={c} size={18} onClick={()=>execText('foreColor',c)}/>)}
    <span style={{fontSize:11.5,color:'var(--sitm-text)',marginLeft:'auto'}}>Formatting the selected text</span>
  </div>;
  if (!sel) return <div style={wrap}>
    <span style={{display:'flex',alignItems:'center',gap:8,fontSize:12.5,color:'var(--sitm-text)'}}><Icon name="edit" size={14}/>Click any text to edit it. Click a shape or element to move, resize, or restyle it. Select text to change its font, size, or color.</span>
  </div>;
  const common = <React.Fragment>
    <ToolSep/>
    <OpacityCtl value={sel.opacity} onChange={v=>onChange(sel.id,{opacity:v})}/>
    <ToolSep/>
    <TinyBtn icon="chevR" label="Forward" onClick={()=>onLayer(sel.id,1)}/>
    <TinyBtn icon="chevL" label="Back" onClick={()=>onLayer(sel.id,-1)}/>
    <TinyBtn icon="tpl" label="Duplicate" onClick={()=>onDuplicate(sel.id)}/>
    <TinyBtn icon="trash" label="Delete" danger onClick={()=>onDelete(sel.id)}/>
  </React.Fragment>;
  if (sel.type==='shape') return <div style={wrap}>
    <span style={{fontSize:11.5,fontWeight:600,color:'var(--sitm-teal-deep)',textTransform:'uppercase',letterSpacing:'0.06em',marginRight:4}}>Shape</span>
    {CS_PALETTE.map(([n,c])=><Swatch key={c} color={c} size={20} active={sel.fill===c&&!sel.gradient} onClick={()=>onChange(sel.id,{fill:c})}/>)}
    <ToolSep/>
    <TinyBtn label="Gradient" active={!!sel.gradient} onClick={()=>onChange(sel.id,{gradient:!sel.gradient,fill2:sel.fill2||'#ffffff'})}/>
    {sel.gradient && <span style={{display:'inline-flex',alignItems:'center',gap:5}}>
      <span style={{fontSize:11.5,color:'var(--sitm-text)'}}>to</span>
      {CS_PALETTE.map(([n,c])=><Swatch key={c} color={c} size={16} active={sel.fill2===c} onClick={()=>onChange(sel.id,{fill2:c})}/>)}
    </span>}
    {common}
  </div>;
  if (sel.type==='text') return <div style={wrap}>
    <span style={{fontSize:11.5,fontWeight:600,color:'var(--sitm-teal-deep)',textTransform:'uppercase',letterSpacing:'0.06em',marginRight:4}}>Text box</span>
    <span style={{position:'relative',display:'inline-block',width:130}}>
      <select value={sel.font} onChange={e=>onChange(sel.id,{font:e.target.value})} style={{width:'100%',appearance:'none',WebkitAppearance:'none',fontFamily:'var(--sitm-font-body)',fontSize:12,fontWeight:500,padding:'6px 24px 6px 10px',background:'#fff',border:'1px solid var(--sitm-border)',borderRadius:7,cursor:'pointer',color:'var(--sitm-text)'}}>
        {CS_FONTS.map(f=><option key={f} value={f}>{f}</option>)}
      </select>
      <span style={{position:'absolute',right:8,top:'50%',transform:'translateY(-50%)',pointerEvents:'none',color:'var(--sitm-text)'}}><Icon name="chevR" size={11} style={{transform:'rotate(90deg)'}}/></span>
    </span>
    <span style={{display:'inline-flex',alignItems:'center',border:'1px solid var(--sitm-border)',borderRadius:7,overflow:'hidden'}}>
      <button onClick={()=>onChange(sel.id,{size:Math.max(9,sel.size-2)})} style={{border:'none',background:'#fff',cursor:'pointer',padding:'5px 9px',fontFamily:'var(--sitm-font-body)',fontWeight:600}}>-</button>
      <span style={{fontSize:12,fontWeight:600,padding:'0 6px',minWidth:24,textAlign:'center'}}>{sel.size}</span>
      <button onClick={()=>onChange(sel.id,{size:Math.min(96,sel.size+2)})} style={{border:'none',background:'#fff',cursor:'pointer',padding:'5px 9px',fontFamily:'var(--sitm-font-body)',fontWeight:600}}>+</button>
    </span>
    <TinyBtn label="B" active={!!sel.bold} onClick={()=>onChange(sel.id,{bold:!sel.bold})}/>
    <TinyBtn label="I" active={!!sel.italic} onClick={()=>onChange(sel.id,{italic:!sel.italic})}/>
    <TinyBtn label="U" active={!!sel.underline} onClick={()=>onChange(sel.id,{underline:!sel.underline})}/>
    <ToolSep/>
    {CS_PALETTE.map(([n,c])=><Swatch key={c} color={c} size={20} active={sel.color===c} onClick={()=>onChange(sel.id,{color:c})}/>)}
    {common}
  </div>;
  return <div style={wrap}>
    <span style={{fontSize:11.5,fontWeight:600,color:'var(--sitm-teal-deep)',textTransform:'uppercase',letterSpacing:'0.06em',marginRight:4}}>Element</span>
    <span style={{fontSize:12,color:'var(--sitm-text)'}}>Drag to move. Use the corners to resize.</span>
    {common}
  </div>;
}
function SaveElementModal({ open, onClose, cats, onSave, hasSelection }) {
  const [name,setName] = React.useState('My element');
  const [cat,setCat] = React.useState(cats[1]||cats[0]);
  React.useEffect(()=>{ if(open){setName('My element');setCat(cats.includes('Shapes')?'Shapes':cats[1]||cats[0]);} },[open]);
  return <Modal open={open} onClose={onClose} width={440}>
    <H2 style={{fontSize:20}}>Save as element</H2>
    <Sub style={{marginTop:6,marginBottom:16}}>{hasSelection ? 'The selected piece goes into your Elements library so you can drop it onto any page.' : 'Select a shape, text box, or element on the page first, then save it here.'}</Sub>
    {hasSelection && <div>
      <div style={{fontSize:12.5,fontWeight:600,marginBottom:6}}>Name</div>
      <input value={name} onChange={e=>setName(e.target.value)} style={{width:'100%',boxSizing:'border-box',fontFamily:'var(--sitm-font-body)',fontSize:14,padding:'9px 12px',border:'1px solid rgba(62,71,97,.2)',outline:'none',color:'var(--sitm-text)',borderRadius:8}}/>
      <div style={{fontSize:12.5,fontWeight:600,margin:'14px 0 6px'}}>Category</div>
      <span style={{position:'relative',display:'block'}}>
        <select value={cat} onChange={e=>setCat(e.target.value)} style={{width:'100%',appearance:'none',WebkitAppearance:'none',fontFamily:'var(--sitm-font-body)',fontSize:13,padding:'9px 30px 9px 12px',background:'#fff',border:'1px solid var(--sitm-border)',borderRadius:8,cursor:'pointer',color:'var(--sitm-text)'}}>
          {cats.filter(c=>c!=='All').map(c=><option key={c} value={c}>{c}</option>)}
        </select>
        <span style={{position:'absolute',right:10,top:'50%',transform:'translateY(-50%)',pointerEvents:'none',color:'var(--sitm-text)'}}><Icon name="chevR" size={12} style={{transform:'rotate(90deg)'}}/></span>
      </span>
      <div style={{display:'flex',justifyContent:'flex-end',gap:10,marginTop:20}}>
        <Btn kind="ghost" onClick={onClose}>Cancel</Btn>
        <Btn onClick={()=>onSave(name,cat)}>Save</Btn>
      </div>
    </div>}
    {!hasSelection && <div style={{display:'flex',justifyContent:'flex-end',marginTop:8}}><Btn kind="ghost" onClick={onClose}>Got it</Btn></div>}
  </Modal>;
}
Object.assign(window, { CS_PALETTE, CS_FONTS, CS_SHAPES, Swatch, shapeStyle, CanvasObject, SelectionToolbar, TinyBtn, SaveElementModal });
