/* ============ Shared components ============ */
const { useState, useMemo, useEffect, useRef } = React;

/* ---- status pill ---- */
function StatusPill({status, map}){
  const m = (map||SW.STATUS)[status] || {label:status, pill:'pill-gray'};
  return <span className={'pill '+m.pill}><span className="pdot"></span>{m.label}</span>;
}

/* ---- sidebar ---- */
const NAV = [
  {grp:'Входящая воронка', items:[
    {key:'dashboard', label:'Дашборд', ic:'home'},
    {key:'inbox', label:'Входящие', ic:'bell'},
    {key:'deals', label:'Сделки', ic:'orders'},
    {key:'quotes', label:'Котировки', ic:'calc'},
    {key:'kp', label:'КП', ic:'doc'},
    {key:'contractors', label:'Контрагенты', ic:'admin'},
  ]},
  {grp:'Исходящая воронка', items:[
    {key:'tenders', label:'Тендеры', ic:'claims'},
    {key:'leads', label:'Лиды', ic:'users'},
  ]},
  {grp:'Контроль', items:[
    {key:'assistant', label:'ИИ-ассистент', ic:'support'},
    {key:'agents', label:'Агенты', ic:'sparkle', iconFill:true},
    {key:'audit', label:'Аудит', ic:'shield'},
    {key:'analytics', label:'Аналитика', ic:'trend'},
    {key:'settings', label:'Настройки', ic:'settings'},
  ]},
];

function Sidebar({view, setView, badges}){
  const [wsOpen,setWsOpen]=useState(false);
  return (
    <aside className="sidebar">
      <div className="ws-switch-wrap">
        <button className="ws-switch" onClick={()=>setWsOpen(o=>!o)}>
          <div className="brand-mark">S</div>
          <div style={{flex:1,textAlign:'left',minWidth:0}}>
            <div className="brand-name">Silkway</div>
            <div className="brand-sub">Сотрудник · логцентр</div>
          </div>
          <span style={{opacity:.6,transition:'transform .15s',transform:wsOpen?'rotate(180deg)':'none'}}><Icon name="chevD" size={16}/></span>
        </button>
        {wsOpen && (
          <>
            <div style={{position:'fixed',inset:0,zIndex:49}} onClick={()=>setWsOpen(false)}/>
            <div className="ws-pop">
              <div className="ws-pop-label">Рабочее пространство</div>
              <div className="ws-item active">
                <div className="ws-item-ic"><Icon name="admin" size={16}/></div>
                <div style={{flex:1}}>
                  <div className="ws-item-name">Сотрудник Silkway</div>
                  <div className="ws-item-sub">Рабочее место логцентра</div>
                </div>
                <Icon name="check" size={16}/>
              </div>
              <a className="ws-item" href="../design_handoff_silkway_portal/Silkway%20Portal.html">
                <div className="ws-item-ic" style={{background:'var(--blue)'}}><Icon name="box" size={16}/></div>
                <div style={{flex:1}}>
                  <div className="ws-item-name">Клиент</div>
                  <div className="ws-item-sub">Кабинет грузовладельца</div>
                </div>
              </a>
            </div>
          </>
        )}
      </div>
      <nav className="nav" style={{overflowY:'auto',flex:1,marginRight:-8,paddingRight:8}}>
        {NAV.map(g=>(
          <div className="nav-group" key={g.grp}>
            <div className="nav-label">{g.grp}</div>
            {g.items.map(it=>(
              <button key={it.key} className={'nav-item'+(view===it.key?' active':'')} onClick={()=>setView(it.key)}>
                <span className="nav-ic">
                  {it.iconFill
                    ? <Icon name={it.ic} size={19} fill="currentColor"/>
                    : <Icon name={it.ic} size={19} sw={view===it.key?2.1:1.8}/>}
                </span>
                <span className="lbl">{it.label}</span>
                {badges[it.key]?<span className={'nav-badge'+(badges[it.key+'_danger']?' nav-badge-danger':'')}>{badges[it.key]}</span>:null}
              </button>
            ))}
          </div>
        ))}
      </nav>
      <div className="side-foot">
        <div className="user-chip" onClick={()=>setView('settings')}>
          <div className="avatar">{SW.me.initials}</div>
          <div className="user-meta">
            <div className="user-name">{SW.me.name}</div>
            <div className="user-org">{SW.me.role} · {SW.me.company}</div>
          </div>
        </div>
      </div>
    </aside>
  );
}

/* ---- topbar ---- */
function TopBar({title, search, setSearch, onCreate, createLabel, onLogout}){
  return (
    <div className="topbar">
      <div className="tb-title">{title}</div>
      <div className="tb-search">
        <Icon name="search" size={17}/>
        <input value={search} onChange={e=>setSearch(e.target.value)} placeholder="Поиск по компании, сделке, тендеру…"/>
      </div>
      <div className="tb-actions">
        <button className="icon-btn" title="Справка"><Icon name="info" size={19}/></button>
        <button className="icon-btn" title="Уведомления"><Icon name="bell" size={19}/><span className="dot"></span></button>
        {onCreate && <button className="btn btn-dark" onClick={onCreate}><Icon name="plus" size={18}/>{createLabel||'Создать'}</button>}
      </div>
    </div>
  );
}

/* ---- generic controls ---- */
function Checkbox({on, onChange, stop}){
  return <div className={'cbx'+(on?' on':'')} onClick={e=>{if(stop)e.stopPropagation();onChange&&onChange(!on);}}><Icon name="check" size={13} sw={3}/></div>;
}
function Toggle({on, onChange}){
  return <div className={'sw-tog'+(on?' on':'')} onClick={()=>onChange&&onChange(!on)}></div>;
}
function Radio({on, label, onClick}){
  return <div className={'radio'+(on?' on':'')} onClick={onClick}><span className="dot"></span>{label}</div>;
}
function Seg({value, options, onChange}){
  return <div className="seg">{options.map(o=>(
    <button key={o.v} className={value===o.v?'on':''} onClick={()=>onChange(o.v)}>{o.ic&&<Icon name={o.ic} size={15} sw={2.2}/>}{o.label}</button>
  ))}</div>;
}

/* ---- donut ---- */
function Donut({segments, size=170, stroke=24}){
  const r=(size-stroke)/2, C=2*Math.PI*r;
  const total=segments.reduce((s,x)=>s+x.value,0)||1; let acc=0;
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      <g transform={`rotate(-90 ${size/2} ${size/2})`}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="#efefec" strokeWidth={stroke}/>
        {segments.map((s,i)=>{
          const len=(s.value/total)*C, dash=`${len} ${C-len}`, off=-acc; acc+=len;
          return <circle key={i} cx={size/2} cy={size/2} r={r} fill="none" stroke={s.color} strokeWidth={stroke} strokeDasharray={dash} strokeDashoffset={off}/>;
        })}
      </g>
    </svg>
  );
}

/* ---- sparkline ---- */
function Sparkline({data, w=120, h=36, color='#494fdf', fill=true}){
  const max=Math.max(...data), min=Math.min(...data), rng=(max-min)||1;
  const pts=data.map((v,i)=>[i/(data.length-1)*w, h-((v-min)/rng)*(h-6)-3]);
  const d=pts.map((p,i)=>(i?'L':'M')+p[0].toFixed(1)+' '+p[1].toFixed(1)).join(' ');
  const area=d+` L ${w} ${h} L 0 ${h} Z`;
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none">
      {fill && <path d={area} fill={color} opacity=".10"/>}
      <path d={d} fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}

/* ---- line chart (two series) ---- */
function LineChart({labels, series, h=240}){
  const w=820, padL=44, padB=28, padT=12, padR=10;
  const all=series.flatMap(s=>s.data);
  const max=Math.max(...all), min=0, rng=(max-min)||1;
  const iw=w-padL-padR, ih=h-padB-padT;
  const x=i=>padL + i/(labels.length-1)*iw;
  const y=v=>padT + ih - ((v-min)/rng)*ih;
  const ticks=4;
  return (
    <svg viewBox={`0 0 ${w} ${h}`} width="100%" style={{display:'block'}}>
      {[...Array(ticks+1)].map((_,i)=>{
        const gv=min+rng*i/ticks, gy=y(gv);
        return <g key={i}>
          <line x1={padL} y1={gy} x2={w-padR} y2={gy} stroke="#eee" strokeWidth="1"/>
          <text x={padL-10} y={gy+4} textAnchor="end" fontSize="11" fill="#9aa3ab">{Math.round(gv)}</text>
        </g>;
      })}
      {labels.map((l,i)=>(i%2===0)&&<text key={i} x={x(i)} y={h-8} textAnchor="middle" fontSize="11" fill="#9aa3ab">{l}</text>)}
      {series.map((s,si)=>{
        const d=s.data.map((v,i)=>(i?'L':'M')+x(i).toFixed(1)+' '+y(v).toFixed(1)).join(' ');
        const area=d+` L ${x(s.data.length-1)} ${y(0)} L ${x(0)} ${y(0)} Z`;
        return <g key={si}>
          <path d={area} fill={s.color} opacity=".07"/>
          <path d={d} fill="none" stroke={s.color} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/>
          {s.data.map((v,i)=><circle key={i} cx={x(i)} cy={y(v)} r="3" fill="#fff" stroke={s.color} strokeWidth="2"/>)}
        </g>;
      })}
    </svg>
  );
}

/* ---- journey timeline ---- */
function Journey({stageIndex, stages}){
  const S=stages||SW.STAGES;
  return (
    <div className="journey">
      {S.map((s,i)=>{
        const cls=i<stageIndex?'done':i===stageIndex?'current':'';
        return (
          <div className={'j-step '+cls} key={s.key}>
            <span className="j-line"></span>
            <div className="j-dot">
              {i<stageIndex?<Icon name="check" size={15} sw={2.6}/>:i===stageIndex?<span className="pulse"></span>:<Icon name={s.ic} size={15}/>}
            </div>
            <div className="j-cap">{s.label}</div>
          </div>
        );
      })}
    </div>
  );
}

/* ---- pagination ---- */
function Pager({total, page, per, setPage, setPer}){
  const pages=Math.max(1,Math.ceil(total/per));
  const from=total===0?0:page*per+1, to=Math.min(total,(page+1)*per);
  return (
    <div className="between" style={{marginTop:18}}>
      <div className="row" style={{gap:14}}>
        <span className="muted" style={{fontSize:14}}>Показано {from}–{to} из {total}</span>
        <select className="select" style={{padding:'7px 32px 7px 12px',fontSize:13}} value={per} onChange={e=>{setPer(+e.target.value);setPage(0);}}>
          {[10,20,30,50].map(n=><option key={n} value={n}>{n} / стр</option>)}
        </select>
      </div>
      <div className="row" style={{gap:8}}>
        <button className="btn btn-light btn-sm" disabled={page===0} onClick={()=>setPage(p=>Math.max(0,p-1))}><Icon name="chevL" size={15}/>Назад</button>
        <span className="muted" style={{fontSize:14,minWidth:60,textAlign:'center'}}>{page+1} / {pages}</span>
        <button className="btn btn-light btn-sm" disabled={page>=pages-1} onClick={()=>setPage(p=>Math.min(pages-1,p+1))}>Вперёд<Icon name="chevR" size={15}/></button>
      </div>
    </div>
  );
}

/* ---- copy mono ---- */
function CopyMono({text, big}){
  const [done,setDone]=useState(false);
  return (
    <button className="link" style={{gap:6,fontWeight:700,fontSize:big?17:14}} onClick={e=>{e.stopPropagation();navigator.clipboard?.writeText(text);setDone(true);setTimeout(()=>setDone(false),1200);}}>
      <span className="mono">{text}</span><Icon name={done?'check':'copy'} size={big?15:13}/>
    </button>
  );
}

/* ---- toast ---- */
function Toast({msg, onDone}){
  useEffect(()=>{const t=setTimeout(onDone,2600);return ()=>clearTimeout(t);},[]);
  return <div className="toast"><Icon name="check" size={18} sw={2.4}/>{msg}</div>;
}

/* ---- page head ---- */
function PageHead({title, sub, children}){
  return (
    <div className="page-head">
      <div><h1>{title}</h1>{sub&&<div className="sub">{sub}</div>}</div>
      <div className="spacer"></div>
      {children}
    </div>
  );
}

/* ---- empty ---- */
function Empty({ic, text}){
  return <div className="empty"><Icon name={ic||'search'} size={28} style={{opacity:.4,marginBottom:10}}/><div>{text}</div></div>;
}

Object.assign(window, { StatusPill, Sidebar, TopBar, Checkbox, Toggle, Radio, Seg, Donut, Sparkline, LineChart, Journey, Pager, CopyMono, Toast, PageHead, Empty, NAV });
