// ============================================================================
// ПОСТАЧАЛЬНИКИ — config management (chat IDs, price columns, balance, cbPrefix)
// Desktop: slide-in panel | Mobile: bottom sheet | Real API: /api/suppliers
// ============================================================================
const { useState, useEffect, useRef, useCallback } = React;

const SUP_AVATAR_COLORS = ["#6366F1","#F59E0B","#10B981","#3B82F6","#EF4444","#8B5CF6","#06B6D4","#F97316"];
const SUP_COLS = Array.from({length:26},(_,i)=>String.fromCharCode(65+i)); // A..Z
const SUP_CURRENCIES = ["₴","$","€"];
const SUP_NOTIFY_DEFAULT = "-5047147114";

// ── helpers ──────────────────────────────────────────────────────────────────
function supInitials(name) {
  const p = (name || "").trim().split(/\s+/).filter(Boolean);
  if (p.length >= 2) return (p[0][0] + p[1][0]).toUpperCase();
  return ((name || "?").replace(/\s/g,"").slice(0,2)||"?").toUpperCase();
}
function supGenColor(str) {
  let h = 0;
  for (let i = 0; i < str.length; i++) h = str.charCodeAt(i) + ((h<<5)-h);
  return SUP_AVATAR_COLORS[Math.abs(h) % SUP_AVATAR_COLORS.length];
}
function supFmtBal(n, cur) {
  if (n == null || isNaN(Number(n))) return "—";
  n = Number(n);
  const frac = (cur === "$" || cur === "€") ? 2 : 0;
  const abs = Math.abs(n).toLocaleString("uk-UA",{minimumFractionDigits:frac,maximumFractionDigits:2}).replace(/ /g," ");
  return (n < 0 ? "− " : "") + abs + " " + cur;
}
function supAutoKey(name, existing) {
  let base = (name||"").toLowerCase().replace(/[^a-z0-9]+/g,"").slice(0,16)||"supplier";
  let k = base, i = 2;
  while ((existing||[]).includes(k)) { k=base+i; i++; }
  return k;
}
function supAutoPrefix(key, name) {
  return ((key||name||"").toLowerCase().replace(/[^a-z0-9а-яіїєґ]+/gi,"").slice(0,12))||"cb";
}
function supBlank() {
  return {
    key:"",name:"",color:SUP_AVATAR_COLORS[Math.floor(Math.random()*SUP_AVATAR_COLORS.length)],active:true,
    groupChatId:"",ttnSameAsGroup:true,ttnChatId:"",
    notifyStandard:true,notifyChatId:SUP_NOTIFY_DEFAULT,
    priceSheetId:"",currency:"₴",
    price:{nameCol:"A",priceCol:"B",articleCol:"",statusCol:"",stockCol:"",dataStartRow:2,searchMode:"standard"},
    balanceSheetId:"",cbPrefix:"",cbAuto:true,balanceType:"standard",
    siteSupplierId:"",
    warrantyMonths:"",warrantyType:"Магазин",   // гарантія постачальника (авто-підстановка в товар)
  };
}
function pluralSup(n) {
  const m=n%10,c=n%100;
  if(m===1&&c!==11) return "постачальник";
  if(m>=2&&m<=4&&(c<10||c>=20)) return "постачальники";
  return "постачальників";
}

// ── sub-components ────────────────────────────────────────────────────────────
function SupAvatar({name,color,size=40,dim}) {
  return (
    <div style={{width:size,height:size,borderRadius:"50%",background:color||supGenColor(name||"?"),flexShrink:0,
      display:"flex",alignItems:"center",justifyContent:"center",color:"#fff",fontWeight:700,
      fontSize:size*0.36,letterSpacing:"0.01em",opacity:dim?0.5:1,transition:"opacity 150ms"}}>
      {supInitials(name)}
    </div>
  );
}

function ActiveBadge({active}) {
  const tone = active?"var(--credit)":"var(--fg-muted)";
  const bg   = active?"rgba(16,185,129,.14)":"rgba(148,163,184,.12)";
  return (
    <span style={{display:"inline-flex",alignItems:"center",gap:6,height:22,padding:"0 9px",
      borderRadius:999,fontSize:11,fontWeight:500,color:tone,background:bg,whiteSpace:"nowrap"}}>
      <span style={{width:6,height:6,borderRadius:"50%",background:"currentColor"}}/>
      {active?"Активний":"Неактивний"}
    </span>
  );
}

function SupSwitch({on,onChange}) {
  return (
    <button onClick={()=>onChange(!on)} style={{width:40,height:23,borderRadius:999,border:0,padding:0,cursor:"pointer",flexShrink:0,
      background:on?"var(--accent)":"color-mix(in oklab, var(--fg-primary) 16%, transparent)",
      position:"relative",transition:"background 150ms"}}>
      <span style={{position:"absolute",top:2,left:on?19:2,width:19,height:19,borderRadius:"50%",background:"#fff",transition:"left 150ms"}}/>
    </button>
  );
}

function SupSegmented({value,onChange,options,fullWidth}) {
  return (
    <div style={{display:fullWidth?"flex":"inline-flex",padding:3,background:"var(--bg-base)",
      border:"1px solid var(--border-default)",borderRadius:8,gap:3}}>
      {options.map(o=>{
        const on=value===o.value;
        return <button key={o.value} onClick={()=>onChange(o.value)} style={{
          flex:fullWidth?1:undefined,height:30,padding:"0 14px",border:0,borderRadius:6,
          cursor:"pointer",fontFamily:"inherit",fontSize:12,fontWeight:500,
          background:on?"var(--accent)":"transparent",color:on?"#fff":"var(--fg-secondary)",transition:"background 120ms"}}>
          {o.label}
        </button>;
      })}
    </div>
  );
}

const supFieldLabel = {fontSize:11,fontWeight:500,letterSpacing:"0.03em",textTransform:"uppercase",color:"var(--fg-muted)",marginBottom:7,display:"block"};

function SupField({label,hint,error,children}) {
  return (
    <div style={{display:"flex",flexDirection:"column"}}>
      <label style={supFieldLabel}>{label}</label>
      {children}
      {error&&<span style={{fontSize:11,color:"var(--danger)",marginTop:6}}>{error}</span>}
      {!error&&hint&&<span style={{fontSize:11,color:"var(--fg-muted)",marginTop:6}}>{hint}</span>}
    </div>
  );
}

function SupInput({value,onChange,placeholder,mono,error,disabled,numeric,large}) {
  const h = large?42:38, fs = large?14:13;
  return (
    <input className="supp-input" value={value??""} placeholder={placeholder} disabled={disabled}
      inputMode={numeric?"numeric":undefined}
      onChange={e=>onChange(numeric?e.target.value.replace(/[^\d-]/g,""):e.target.value)}
      style={{width:"100%",boxSizing:"border-box",height:h,padding:"0 12px",background:"var(--bg-base)",
        color:"var(--fg-primary)",border:"1px solid var(--border-default)",borderRadius:large?9:7,
        fontSize:fs,fontFamily:"inherit",outline:"none",transition:"border-color 150ms, box-shadow 150ms",
        ...(mono?{fontFamily:"var(--font-mono)",fontVariantNumeric:"tabular-nums"}:{}),
        ...(error?{borderColor:"var(--danger)"}:{}),
        ...(disabled?{background:"var(--bg-panel)",color:"var(--fg-muted)",cursor:"not-allowed"}:{}),
      }}/>
  );
}

function SupSelect({value,onChange,options,mono,large}) {
  const h = large?42:38, fs = large?14:13;
  return (
    <div style={{position:"relative"}}>
      <select className="supp-input" value={value} onChange={e=>onChange(e.target.value)} style={{
        width:"100%",boxSizing:"border-box",height:h,padding:`0 30px 0 12px`,
        background:"var(--bg-base)",color:"var(--fg-primary)",border:"1px solid var(--border-default)",
        borderRadius:large?9:7,fontSize:fs,fontFamily:"inherit",outline:"none",
        appearance:"none",WebkitAppearance:"none",cursor:"pointer",
        ...(mono?{fontFamily:"var(--font-mono)"}:{}),
      }}>
        {options.map(o=><option key={o.value} value={o.value}>{o.label}</option>)}
      </select>
      <span style={{position:"absolute",right:10,top:"50%",transform:"translateY(-50%)",pointerEvents:"none",color:"var(--fg-muted)",display:"inline-flex"}}>
        <Icon name="chevron-down" size={15}/>
      </span>
    </div>
  );
}

function SupRowBetween({label,sub,children}) {
  return (
    <div style={{display:"flex",alignItems:"center",gap:12}}>
      <div style={{flex:1,minWidth:0}}>
        <div style={{fontSize:13,color:"var(--fg-primary)"}}>{label}</div>
        {sub&&<div style={{fontSize:11,color:"var(--fg-muted)",marginTop:2}}>{sub}</div>}
      </div>
      {children}
    </div>
  );
}

function SupSection({title,children}) {
  return (
    <div style={{display:"flex",flexDirection:"column",gap:16}}>
      <div style={{fontSize:12,fontWeight:600,color:"var(--fg-secondary)",letterSpacing:"0.02em",display:"flex",alignItems:"center",gap:10}}>
        {title}<span style={{flex:1,height:1,background:"var(--border-subtle)"}}/>
      </div>
      {children}
    </div>
  );
}

const SUP_PRICE_FIELDS = [
  {key:"nameCol",label:"Назва"},{key:"priceCol",label:"Ціна"},
  {key:"articleCol",label:"Артикул"},{key:"statusCol",label:"Статус"},{key:"stockCol",label:"Кількість"},
];

function ColumnMap({price,onField,large}) {
  const colOpts = [{value:"",label:"Немає"},...SUP_COLS.map(c=>({value:c,label:c}))];
  return (
    <div style={{display:"grid",gridTemplateColumns:large?"1fr 1fr":"repeat(auto-fit, minmax(110px, 1fr))",gap:12}}>
      {SUP_PRICE_FIELDS.map(f=>(
        <SupField key={f.key} label={f.label}>
          <SupSelect value={price[f.key]||""} onChange={v=>onField(f.key,v)} options={colOpts} mono large={large}/>
        </SupField>
      ))}
    </div>
  );
}

// ── Form body (shared desktop+mobile) ────────────────────────────────────────
function SupFormBody({form,setForm,errors,isNew,existingKeys,isMobile}) {
  const set = patch => setForm(f=>({...f,...patch}));
  const setP = (k,v) => setForm(f=>({...f,price:{...f.price,[k]:v}}));
  const ttnVal = form.ttnSameAsGroup ? form.groupChatId : form.ttnChatId;
  const cbVal  = form.cbAuto ? supAutoPrefix(form.key,form.name) : form.cbPrefix;
  const L = isMobile;

  return (
    <div style={{display:"flex",flexDirection:"column",gap:28}}>
      {/* GENERAL */}
      <SupSection title="Загальне">
        <div style={{display:"grid",gridTemplateColumns:"1.4fr 1fr",gap:14}}>
          <SupField label="Назва" error={errors.name}>
            <SupInput value={form.name} placeholder="DeviceHub" error={errors.name} large={L}
              onChange={v=>set({name:v,...(isNew?{key:supAutoKey(v,existingKeys)}:{})})}/>
          </SupField>
          <SupField label="Ключ" hint={isNew?"Унікальний, латиницею":"Не змінюється"} error={errors.key}>
            <SupInput value={form.key} placeholder="devicehub" mono disabled={!isNew} error={errors.key} large={L}
              onChange={v=>set({key:v.toLowerCase().replace(/[^a-z0-9]/g,"")})}/>
          </SupField>
        </div>

        <SupField label="Колір аватарки">
          <div style={{display:"flex",gap:8,flexWrap:"wrap"}}>
            {SUP_AVATAR_COLORS.map(c=>(
              <button key={c} onClick={()=>set({color:c})} style={{
                width:30,height:30,borderRadius:"50%",background:c,cursor:"pointer",
                border:form.color===c?"2px solid var(--fg-primary)":"2px solid transparent",
                boxShadow:form.color===c?"0 0 0 2px var(--bg-base)":"none",transition:"all 120ms",
              }}/>
            ))}
          </div>
        </SupField>

        <SupField label="Group Chat ID" error={errors.groupChatId}>
          <SupInput value={form.groupChatId} placeholder="-1001234567890" mono numeric error={errors.groupChatId} large={L}
            onChange={v=>set({groupChatId:v})}/>
        </SupField>

        <SupField label="TTN Chat ID">
          <div style={{display:"flex",flexDirection:"column",gap:10}}>
            <SupRowBetween label="Той самий, що Group" sub="Накладні йдуть у груповий чат">
              <SupSwitch on={form.ttnSameAsGroup} onChange={v=>set({ttnSameAsGroup:v})}/>
            </SupRowBetween>
            {form.ttnSameAsGroup
              ? <SupInput value={ttnVal} onChange={()=>{}} mono disabled large={L}/>
              : <SupInput value={form.ttnChatId} placeholder="-1001234567890" mono numeric large={L} onChange={v=>set({ttnChatId:v})}/>
            }
          </div>
        </SupField>

        <SupField label="Notify Chat ID">
          <div style={{display:"flex",flexDirection:"column",gap:10}}>
            <SupRowBetween label="Стандартний" sub={SUP_NOTIFY_DEFAULT}>
              <SupSwitch on={form.notifyStandard} onChange={v=>set({notifyStandard:v})}/>
            </SupRowBetween>
            {!form.notifyStandard&&(
              <SupInput value={form.notifyChatId} placeholder="-1009999999999" mono numeric large={L} onChange={v=>set({notifyChatId:v})}/>
            )}
          </div>
        </SupField>

        <SupRowBetween label="Активний" sub="Неактивні не беруть участі в обробці">
          <SupSwitch on={form.active} onChange={v=>set({active:v})}/>
        </SupRowBetween>
      </SupSection>

      {/* PRICE */}
      <SupSection title="Прайс">
        <SupField label="Sheet ID" error={errors.priceSheetId}>
          <SupInput value={form.priceSheetId} placeholder="1AbqPr0Sh33tK3y…" mono error={errors.priceSheetId} large={L}
            onChange={v=>set({priceSheetId:v})}/>
        </SupField>
        <div>
          <label style={supFieldLabel}>Колонки</label>
          <ColumnMap price={form.price} onField={setP} large={L}/>
        </div>
        <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:14}}>
          <SupField label="Рядок початку">
            <SupSelect value={String(form.price.dataStartRow)} onChange={v=>setP("dataStartRow",Number(v))}
              options={Array.from({length:20},(_,i)=>i+1).map(n=>({value:String(n),label:String(n)}))} mono large={L}/>
          </SupField>
          <SupField label="Режим пошуку">
            <SupSelect value={form.price.searchMode} onChange={v=>setP("searchMode",v)} large={L}
              options={[{value:"standard",label:"Standard"},{value:"token",label:"Token"}]}/>
          </SupField>
        </div>
      </SupSection>

      {/* BALANCE */}
      <SupSection title="Баланс">
        <SupField label="Sheet ID">
          <SupInput value={form.balanceSheetId} placeholder="1Bal-…" mono large={L} onChange={v=>set({balanceSheetId:v})}/>
        </SupField>
        <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:14,alignItems:"start"}}>
          <SupField label="Валюта">
            <SupSegmented value={form.currency} onChange={v=>set({currency:v})}
              options={SUP_CURRENCIES.map(c=>({value:c,label:c}))} fullWidth={L}/>
          </SupField>
          <SupField label="Тип балансу">
            <SupSegmented value={form.balanceType} onChange={v=>set({balanceType:v})}
              options={[{value:"standard",label:"Standard"},{value:"custom",label:"Custom"}]} fullWidth={L}/>
          </SupField>
        </div>
        <SupField label="cbPrefix">
          <div style={{display:"flex",flexDirection:"column",gap:10}}>
            <SupRowBetween label="Авто" sub="Генерується з ключа">
              <SupSwitch on={form.cbAuto} onChange={v=>set({cbAuto:v})}/>
            </SupRowBetween>
            <SupInput value={cbVal} placeholder="cbprefix" mono disabled={form.cbAuto} large={L}
              onChange={v=>set({cbPrefix:v})}/>
          </div>
        </SupField>
        <SupField label="Horoshop ID (постачальник на сайті)">
          <SupInput value={form.siteSupplierId} placeholder="напр. 21" mono numeric large={L}
            onChange={v=>set({siteSupplierId:v})}/>
        </SupField>
        <SupField label="🛡 Гарантія постачальника" hint="підставляється автоматично при додаванні товару (для чеків теж)">
          <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:14,alignItems:"start"}}>
            <SupInput value={form.warrantyMonths||""} placeholder="міс., напр. 12" mono numeric large={L}
              onChange={v=>set({warrantyMonths:v})}/>
            <SupSegmented value={form.warrantyType||"Магазин"} onChange={v=>set({warrantyType:v})}
              options={[{value:"Магазин",label:"Магазин"},{value:"Виробник",label:"Виробник"}]} fullWidth={L}/>
          </div>
        </SupField>
      </SupSection>
    </div>
  );
}

// ── Desktop form panel ────────────────────────────────────────────────────────
function SupDesktopForm({initial,isNew,existingKeys,onCancel,onSave,saving}) {
  const [form,setForm] = useState(()=>JSON.parse(JSON.stringify(initial)));
  const [errors,setErrors] = useState({});

  const validate = () => {
    const e={};
    if(!form.name.trim()) e.name="Вкажіть назву";
    if(!form.key.trim()) e.key="Вкажіть ключ";
    else if(isNew&&existingKeys.includes(form.key.trim())) e.key="Такий ключ вже існує";
    if(!form.groupChatId.trim()) e.groupChatId="Обов'язкове поле";
    if(!form.priceSheetId.trim()) e.priceSheetId="Вкажіть Sheet ID прайсу";
    setErrors(e);
    return !Object.keys(e).length;
  };

  const submit = () => {
    if(!validate()) return;
    const cbVal = form.cbAuto ? supAutoPrefix(form.key,form.name) : form.cbPrefix;
    onSave({
      ...form,key:form.key.trim(),name:form.name.trim(),
      ttnChatId:form.ttnSameAsGroup?form.groupChatId:form.ttnChatId,
      notifyChatId:form.notifyStandard?SUP_NOTIFY_DEFAULT:form.notifyChatId,
      cbPrefix:cbVal,
    });
  };

  const hasErrors = Object.keys(errors).length>0;

  return (
    <div style={{position:"absolute",inset:0,zIndex:50}}>
      <div onClick={onCancel} style={{position:"absolute",inset:0,background:"rgba(0,0,0,.6)",animation:"supFade 150ms ease"}}/>
      <div style={{position:"absolute",top:0,right:0,bottom:0,width:520,maxWidth:"100%",background:"var(--bg-base)",
        borderLeft:"1px solid var(--border-subtle)",boxShadow:"var(--shadow-2)",
        display:"flex",flexDirection:"column",animation:"supPanelIn 200ms cubic-bezier(.2,0,0,1)"}}>
        {/* header */}
        <div style={{padding:"16px 24px",borderBottom:"1px solid var(--border-subtle)",display:"flex",alignItems:"center",gap:14,flexShrink:0}}>
          <SupAvatar name={form.name||"?"} color={form.color} size={40}/>
          <div style={{flex:1,minWidth:0}}>
            <div style={{fontSize:16,fontWeight:600,color:"var(--fg-primary)"}}>{isNew?"Новий постачальник":(form.name||"Постачальник")}</div>
            <div style={{fontSize:12,color:"var(--fg-muted)"}}>{isNew?"Заповніть налаштування":"Редагування налаштувань"}</div>
          </div>
          <button onClick={onCancel} style={{width:34,height:34,border:"1px solid var(--border-default)",background:"var(--bg-raised)",
            color:"var(--fg-secondary)",borderRadius:8,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>
            <Icon name="x" size={16}/>
          </button>
        </div>
        {/* body */}
        <div style={{flex:1,overflow:"auto",padding:"22px 24px"}}>
          <SupFormBody form={form} setForm={setForm} errors={errors} isNew={isNew} existingKeys={existingKeys} isMobile={false}/>
        </div>
        {/* footer */}
        <div style={{padding:"14px 24px",borderTop:"1px solid var(--border-subtle)",display:"flex",alignItems:"center",gap:10,flexShrink:0,background:"var(--bg-panel)"}}>
          {hasErrors&&(
            <span style={{fontSize:12,color:"var(--danger)",display:"inline-flex",alignItems:"center",gap:6,flex:1}}>
              <Icon name="alert-circle" size={14}/> Перевірте виділені поля
            </span>
          )}
          <div style={{flex:hasErrors?undefined:1}}/>
          <Button variant="secondary" size="md" onClick={onCancel} disabled={saving}>Скасувати</Button>
          <Button variant="primary" size="md" leftIcon={saving?"loader":"check"} onClick={submit} disabled={saving}>
            {saving?"Зберігаємо…":"Зберегти"}
          </Button>
        </div>
      </div>
    </div>
  );
}

// ── Mobile bottom sheet ───────────────────────────────────────────────────────
function SupMobileSheet({initial,isNew,existingKeys,onClose,onSave,saving}) {
  const [form,setForm] = useState(()=>JSON.parse(JSON.stringify(initial)));
  const [errors,setErrors] = useState({});

  const submit = () => {
    const e={};
    if(!form.name.trim()) e.name="Вкажіть назву";
    if(!form.key.trim()) e.key="Вкажіть ключ";
    else if(isNew&&existingKeys.includes(form.key.trim())) e.key="Ключ вже існує";
    if(!form.groupChatId.trim()) e.groupChatId="Обов'язкове поле";
    if(!form.priceSheetId.trim()) e.priceSheetId="Вкажіть Sheet ID прайсу";
    setErrors(e);
    if(Object.keys(e).length) return;
    const cbVal = form.cbAuto ? supAutoPrefix(form.key,form.name) : form.cbPrefix;
    onSave({
      ...form,key:form.key.trim(),name:form.name.trim(),
      ttnChatId:form.ttnSameAsGroup?form.groupChatId:form.ttnChatId,
      notifyChatId:form.notifyStandard?SUP_NOTIFY_DEFAULT:form.notifyChatId,
      cbPrefix:cbVal,
    });
  };

  return (
    <div onClick={onClose} style={{position:"absolute",inset:0,background:"rgba(0,0,0,.6)",zIndex:30,display:"flex",flexDirection:"column",justifyContent:"flex-end"}}>
      <div onClick={e=>e.stopPropagation()} style={{background:"var(--bg-panel)",borderRadius:"16px 16px 0 0",height:"94%",
        display:"flex",flexDirection:"column",animation:"supSlideUp 220ms cubic-bezier(.2,0,0,1)"}}>
        <div style={{display:"flex",justifyContent:"center",padding:"8px 0 4px"}}>
          <div style={{width:36,height:4,borderRadius:2,background:"rgba(255,255,255,.2)"}}/>
        </div>
        <div style={{display:"flex",alignItems:"center",gap:12,padding:"6px 16px 12px",borderBottom:"1px solid var(--border-subtle)"}}>
          <SupAvatar name={form.name||"?"} color={form.color} size={38}/>
          <div style={{flex:1,minWidth:0}}>
            <div style={{fontSize:16,fontWeight:600,color:"var(--fg-primary)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{isNew?"Новий постачальник":(form.name||"Постачальник")}</div>
            <div style={{fontSize:12,color:"var(--fg-muted)"}}>{isNew?"Заповніть налаштування":"Редагування"}</div>
          </div>
          <button onClick={onClose} style={{width:32,height:32,border:0,background:"transparent",color:"var(--fg-secondary)",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"}}>
            <Icon name="x" size={18}/>
          </button>
        </div>
        <div style={{flex:1,overflowY:"auto",padding:"18px 16px"}}>
          <SupFormBody form={form} setForm={setForm} errors={errors} isNew={isNew} existingKeys={existingKeys} isMobile={true}/>
        </div>
        <div style={{padding:"12px 16px",borderTop:"1px solid var(--border-subtle)",display:"flex",gap:10,flexShrink:0}}>
          <button onClick={onClose} disabled={saving} style={{flex:1,height:46,border:"1px solid var(--border-default)",background:"var(--bg-raised)",color:"var(--fg-primary)",borderRadius:11,fontSize:14,fontWeight:500,cursor:"pointer",fontFamily:"inherit"}}>Скасувати</button>
          <button onClick={submit} disabled={saving} style={{flex:1.4,height:46,border:0,background:"var(--accent)",color:"#fff",borderRadius:11,fontSize:14,fontWeight:600,cursor:"pointer",fontFamily:"inherit",display:"flex",alignItems:"center",justifyContent:"center",gap:8,opacity:saving?.6:1}}>
            <Icon name={saving?"loader":"check"} size={16}/>{saving?"Зберігаємо…":"Зберегти"}
          </button>
        </div>
      </div>
    </div>
  );
}

// ── Card (desktop) ────────────────────────────────────────────────────────────
function SupCard({s,onEdit,onToggle,onDelete,onWelcome,confirming,onConfirmOpen,onConfirmCancel,balance}) {
  const val = balance!=null&&!isNaN(Number(balance)) ? Number(balance) : null;
  const neg = val!==null&&val<0;
  const tone = neg?"var(--debit)":"var(--credit)";
  return (
    <div className="supp-card" style={{background:"var(--bg-panel)",border:"1px solid var(--border-subtle)",borderRadius:12,
      padding:18,display:"flex",flexDirection:"column",gap:14,position:"relative",
      transition:"border-color 150ms",opacity:s.active?1:.72}}>
      <div style={{display:"flex",alignItems:"flex-start",gap:12}}>
        <SupAvatar name={s.name} color={s.color||supGenColor(s.name||s.key||"?")} size={44} dim={!s.active}/>
        <div style={{flex:1,minWidth:0}}>
          <div style={{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap"}}>
            <span style={{fontSize:15,fontWeight:600,color:"var(--fg-primary)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",maxWidth:"100%"}}>{s.name}</span>
            <ActiveBadge active={s.active}/>
          </div>
          <div style={{display:"flex",alignItems:"center",gap:8,marginTop:5,fontSize:12,color:"var(--fg-muted)"}}>
            <span style={{fontFamily:"var(--font-mono)"}}>{s.currency||"₴"}</span>
            <span style={{width:3,height:3,borderRadius:"50%",background:"var(--fg-disabled)"}}/>
            <span style={{fontFamily:"var(--font-mono)"}}>cb:{s.cbPrefix||supAutoPrefix(s.key,s.name)}</span>
          </div>
        </div>
      </div>

      <div style={{display:"flex",flexDirection:"column",gap:3}}>
        <span style={{fontSize:11,fontWeight:500,letterSpacing:"0.04em",textTransform:"uppercase",color:"var(--fg-muted)"}}>Поточний баланс</span>
        <span style={{fontFamily:"var(--font-mono)",fontVariantNumeric:"tabular-nums",fontSize:22,fontWeight:700,color:tone,letterSpacing:"-0.01em"}}>
          {val!==null ? supFmtBal(val,s.currency||"₴") : "—"}
        </span>
      </div>

      <div style={{display:"flex",alignItems:"center",gap:8,paddingTop:12,borderTop:"1px solid var(--border-subtle)"}}>
        {confirming ? (
          <div style={{display:"flex",alignItems:"center",gap:8,width:"100%"}}>
            <span style={{fontSize:12,color:"var(--fg-secondary)",flex:1}}>Видалити постачальника?</span>
            <button onClick={e=>{e.stopPropagation();onConfirmCancel();}} style={{height:30,padding:"0 12px",border:"1px solid var(--border-default)",background:"var(--bg-raised)",color:"var(--fg-secondary)",borderRadius:7,cursor:"pointer",fontSize:12,fontFamily:"inherit",fontWeight:500}}>Скасувати</button>
            <button onClick={e=>{e.stopPropagation();onDelete();}} style={{height:30,padding:"0 12px",border:"1px solid rgba(244,63,94,.3)",background:"rgba(244,63,94,.14)",color:"var(--danger)",borderRadius:7,cursor:"pointer",fontSize:12,fontFamily:"inherit",fontWeight:600}}>Видалити</button>
          </div>
        ):(
          <>
            <button onClick={()=>onEdit(s)} style={{height:32,padding:"0 12px",border:"1px solid var(--border-default)",background:"var(--bg-raised)",color:"var(--fg-primary)",borderRadius:7,cursor:"pointer",fontSize:12,fontFamily:"inherit",fontWeight:500,display:"inline-flex",alignItems:"center",gap:7}}>
              <Icon name="pencil" size={14}/> Редагувати
            </button>
            <div style={{flex:1}}/>
            <button onClick={()=>onWelcome(s)} title="Надіслати привітання в групу" style={{width:32,height:32,border:"1px solid var(--border-default)",background:"var(--bg-raised)",color:"var(--fg-secondary)",borderRadius:7,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"}}>
              <Icon name="send" size={15}/>
            </button>
            <button onClick={()=>onToggle(s)} title={s.active?"Деактивувати":"Активувати"} style={{width:32,height:32,border:"1px solid var(--border-default)",background:"var(--bg-raised)",color:s.active?"var(--accent)":"var(--fg-muted)",borderRadius:7,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 150ms"}}>
              <Icon name={s.active?"toggle-right":"toggle-left"} size={16}/>
            </button>
            <button onClick={()=>onConfirmOpen(s.key)} title="Видалити" style={{width:32,height:32,border:"1px solid var(--border-default)",background:"var(--bg-raised)",color:"var(--fg-secondary)",borderRadius:7,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"}}>
              <Icon name="trash-2" size={15}/>
            </button>
          </>
        )}
      </div>
    </div>
  );
}

// ── Mobile Card ───────────────────────────────────────────────────────────────
function SupCardMobile({s,onEdit,onToggle,onDelete,onWelcome,confirming,onConfirmOpen,onConfirmCancel,balance}) {
  const val = balance!=null&&!isNaN(Number(balance)) ? Number(balance) : null;
  const neg = val!==null&&val<0;
  const tone = neg?"var(--debit)":"var(--credit)";
  return (
    <div style={{background:"var(--bg-panel)",border:"1px solid var(--border-subtle)",borderRadius:14,padding:14,
      display:"flex",flexDirection:"column",gap:12,opacity:s.active?1:.72}}>
      <div onClick={()=>onEdit(s)} style={{display:"flex",alignItems:"center",gap:12,cursor:"pointer"}}>
        <SupAvatar name={s.name} color={s.color||supGenColor(s.name||s.key||"?")} size={44} dim={!s.active}/>
        <div style={{flex:1,minWidth:0}}>
          <div style={{display:"flex",alignItems:"center",gap:8}}>
            <span style={{fontSize:15,fontWeight:600,color:"var(--fg-primary)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{s.name}</span>
            <ActiveBadge active={s.active}/>
          </div>
          <div style={{fontFamily:"var(--font-mono)",fontVariantNumeric:"tabular-nums",fontSize:18,fontWeight:700,color:tone,marginTop:3}}>
            {val!==null ? supFmtBal(val,s.currency||"₴") : "—"}
          </div>
          <div style={{fontSize:11,color:"var(--fg-muted)",fontFamily:"var(--font-mono)",marginTop:1}}>
            {s.currency||"₴"} · cb:{s.cbPrefix||supAutoPrefix(s.key,s.name)}
          </div>
        </div>
        <Icon name="chevron-right" size={16} style={{color:"var(--fg-muted)",flexShrink:0}}/>
      </div>
      <div style={{display:"flex",alignItems:"center",gap:8,paddingTop:12,borderTop:"1px solid var(--border-subtle)"}}>
        {confirming ? (
          <>
            <span style={{fontSize:12,color:"var(--fg-secondary)",flex:1}}>Видалити?</span>
            <button onClick={onConfirmCancel} style={{height:34,padding:"0 14px",border:"1px solid var(--border-default)",background:"var(--bg-raised)",color:"var(--fg-secondary)",borderRadius:9,cursor:"pointer",fontSize:13,fontFamily:"inherit",fontWeight:500}}>Ні</button>
            <button onClick={onDelete} style={{height:34,padding:"0 14px",border:"1px solid rgba(244,63,94,.3)",background:"rgba(244,63,94,.14)",color:"var(--danger)",borderRadius:9,cursor:"pointer",fontSize:13,fontFamily:"inherit",fontWeight:600}}>Видалити</button>
          </>
        ):(
          <>
            <button onClick={()=>onEdit(s)} style={{height:36,padding:"0 14px",border:"1px solid var(--border-default)",background:"var(--bg-raised)",color:"var(--fg-primary)",borderRadius:9,cursor:"pointer",fontSize:13,fontFamily:"inherit",fontWeight:500,display:"inline-flex",alignItems:"center",gap:7}}>
              <Icon name="pencil" size={14}/> Редагувати
            </button>
            <div style={{flex:1}}/>
            <button onClick={()=>onWelcome(s)} title="Привітання" style={{width:36,height:36,border:"1px solid var(--border-default)",background:"var(--bg-raised)",color:"var(--fg-secondary)",borderRadius:9,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"}}>
              <Icon name="send" size={15}/>
            </button>
            <button onClick={()=>onToggle(s)} title={s.active?"Деактивувати":"Активувати"} style={{width:36,height:36,border:"1px solid var(--border-default)",background:"var(--bg-raised)",color:s.active?"var(--accent)":"var(--fg-muted)",borderRadius:9,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"}}>
              <Icon name={s.active?"toggle-right":"toggle-left"} size={16}/>
            </button>
            <button onClick={()=>onConfirmOpen(s.key)} style={{width:36,height:36,border:"1px solid var(--border-default)",background:"var(--bg-raised)",color:"var(--fg-secondary)",borderRadius:9,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"}}>
              <Icon name="trash-2" size={15}/>
            </button>
          </>
        )}
      </div>
    </div>
  );
}

// ── Empty state ───────────────────────────────────────────────────────────────
function SupEmpty({onAdd,isMobile}) {
  return (
    <div style={{flex:1,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:18,padding:40,textAlign:"center"}}>
      <div style={{width:64,height:64,borderRadius:16,background:"var(--bg-raised)",border:"1px solid var(--border-default)",display:"flex",alignItems:"center",justifyContent:"center",color:"var(--fg-muted)"}}>
        <Icon name="truck" size={28}/>
      </div>
      <div style={{display:"flex",flexDirection:"column",gap:6,maxWidth:320}}>
        <span style={{fontSize:15,fontWeight:600,color:"var(--fg-primary)"}}>Постачальників ще немає</span>
        <span style={{fontSize:13,color:"var(--fg-muted)"}}>Додайте першого постачальника, щоб налаштувати прайс, чати та баланс.</span>
      </div>
      {isMobile ? (
        <button onClick={onAdd} style={{height:42,padding:"0 18px",border:0,background:"var(--accent)",color:"#fff",borderRadius:11,cursor:"pointer",fontSize:14,fontWeight:600,fontFamily:"inherit",display:"inline-flex",alignItems:"center",gap:8}}>
          <Icon name="plus" size={16}/> Додати постачальника
        </button>
      ) : (
        <Button variant="primary" size="md" leftIcon="plus" onClick={onAdd}>Додати постачальника</Button>
      )}
    </div>
  );
}

// ── Welcome modal (превʼю + надсилання привітання постачальнику) ──────────────
function SupWelcomeModal({supplierKey,onClose,onResult}) {
  const [loading,setLoading] = useState(true);
  const [text,setText]       = useState("");
  const [info,setInfo]       = useState(null);
  const [err,setErr]         = useState(null);
  const [sending,setSending] = useState(false);

  useEffect(()=>{
    let alive=true;
    fetch(`/api/suppliers/${encodeURIComponent(supplierKey)}/welcome`).then(r=>r.json())
      .then(d=>{ if(!alive)return; if(d.ok){ setText(d.text||""); setInfo(d); } else setErr(d.error||"Помилка підготовки"); })
      .catch(e=>{ if(alive) setErr(e.message); })
      .finally(()=>{ if(alive) setLoading(false); });
    return ()=>{ alive=false; };
  },[supplierKey]);

  const noGroup = info && !info.groupChatId;
  const send = () => {
    setSending(true);
    fetch(`/api/suppliers/${encodeURIComponent(supplierKey)}/welcome`,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({text})})
      .then(r=>r.json())
      .then(d=>{ if(d.ok){ onResult(true,'Привітання надіслано постачальнику'); onClose(); } else onResult(false,d.error||'Помилка надсилання'); })
      .catch(e=>onResult(false,e.message))
      .finally(()=>setSending(false));
  };

  return (
    <div style={{position:"absolute",inset:0,zIndex:60,display:"flex",alignItems:"center",justifyContent:"center",padding:20}}>
      <div onClick={onClose} style={{position:"absolute",inset:0,background:"rgba(0,0,0,.6)",animation:"supFade 150ms ease"}}/>
      <div style={{position:"relative",width:560,maxWidth:"100%",maxHeight:"88vh",display:"flex",flexDirection:"column",
        background:"var(--bg-base)",border:"1px solid var(--border-default)",borderRadius:14,boxShadow:"var(--shadow-2)",overflow:"hidden"}}>
        <div style={{padding:"16px 20px",borderBottom:"1px solid var(--border-subtle)",display:"flex",alignItems:"center",gap:12}}>
          <div style={{width:34,height:34,borderRadius:9,background:"color-mix(in oklab, var(--accent) 16%, transparent)",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>
            <Icon name="send" size={16} style={{color:"var(--accent)"}}/>
          </div>
          <div style={{flex:1,minWidth:0}}>
            <div style={{fontSize:15,fontWeight:600,color:"var(--fg-primary)"}}>Привітання постачальнику</div>
            <div style={{fontSize:12,color:"var(--fg-muted)"}}>{supplierKey}{info?.groupChatId?` · група ${info.groupChatId}`:""}</div>
          </div>
          <button onClick={onClose} style={{width:32,height:32,border:"1px solid var(--border-default)",background:"var(--bg-raised)",color:"var(--fg-secondary)",borderRadius:8,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"}}>
            <Icon name="x" size={16}/>
          </button>
        </div>
        <div style={{flex:1,overflow:"auto",padding:"18px 20px"}}>
          {loading ? (
            <div style={{display:"flex",alignItems:"center",justifyContent:"center",gap:10,padding:"40px 0",color:"var(--fg-muted)",fontSize:13}}>
              <Icon name="loader" size={18}/> Готую повідомлення (синк прайсу, баланс)…
            </div>
          ) : err ? (
            <div style={{padding:"14px",borderRadius:9,background:"rgba(244,63,94,.12)",border:"1px solid rgba(244,63,94,.3)",color:"var(--danger)",fontSize:13}}>{err}</div>
          ) : (
            <>
              {noGroup && (
                <div style={{marginBottom:12,padding:"10px 12px",borderRadius:8,background:"rgba(245,158,11,.12)",border:"1px solid rgba(245,158,11,.3)",color:"var(--warning)",fontSize:12.5}}>
                  У постачальника не вказано Group Chat ID — немає куди надсилати.
                </div>
              )}
              <label style={supFieldLabel}>Текст повідомлення</label>
              <textarea value={text} onChange={e=>setText(e.target.value)} rows={12}
                style={{width:"100%",boxSizing:"border-box",padding:"12px",background:"var(--bg-panel)",color:"var(--fg-primary)",
                  border:"1px solid var(--border-default)",borderRadius:9,fontSize:13,fontFamily:"inherit",lineHeight:1.5,resize:"vertical",outline:"none"}}/>
              <div style={{fontSize:11,color:"var(--fg-muted)",marginTop:6}}>HTML-теги (&lt;b&gt;, &lt;code&gt;) застосуються при надсиланні.</div>
            </>
          )}
        </div>
        <div style={{padding:"14px 20px",borderTop:"1px solid var(--border-subtle)",display:"flex",justifyContent:"flex-end",gap:10,background:"var(--bg-panel)"}}>
          <Button variant="secondary" size="md" onClick={onClose} disabled={sending}>Скасувати</Button>
          <Button variant="primary" size="md" leftIcon={sending?"loader":"send"} onClick={send} disabled={loading||sending||!!err||noGroup}>
            {sending?"Надсилаю…":"Надіслати постачальнику"}
          </Button>
        </div>
      </div>
    </div>
  );
}

// ── Main component ────────────────────────────────────────────────────────────
function Suppliers({isMobile}) {
  const [list,setList]           = useState([]);
  const [balances,setBalances]   = useState({});  // key → balance value
  const [loading,setLoading]     = useState(true);
  const [editing,setEditing]     = useState(null);
  const [isNew,setIsNew]         = useState(false);
  const [confirmKey,setConfirmKey] = useState(null);
  const [saving,setSaving]       = useState(false);
  const [toast,setToast]         = useState(null);
  const [welcomeFor,setWelcomeFor] = useState(null);

  const showMsg = (msg,err) => { setToast({msg,err}); setTimeout(()=>setToast(null),3000); };

  // Load suppliers + balances
  const reload = useCallback(async() => {
    setLoading(true);
    try {
      const [supRes,balRes] = await Promise.allSettled([
        fetch('/api/suppliers').then(r=>r.json()),
        fetch('/api/supplier-balances').then(r=>r.json()),
      ]);
      if(supRes.status==='fulfilled'&&supRes.value.ok) {
        const raw = supRes.value.data||{};
        // Перетворюємо об'єкт на масив
        const arr = Object.entries(raw).map(([name,cfg])=>({
          key: name,
          name,
          color: cfg.color || supGenColor(name),
          active: cfg.active!==false,
          groupChatId: String(cfg.groupChatId||""),
          ttnSameAsGroup: String(cfg.ttnChatId||"")===""||(String(cfg.ttnChatId||""))===String(cfg.groupChatId||""),
          ttnChatId: String(cfg.ttnChatId||""),
          notifyStandard: String(cfg.notifyChatId||"")===""||String(cfg.notifyChatId||"")===-5047147114||String(cfg.notifyChatId||"")===""+SUP_NOTIFY_DEFAULT,
          notifyChatId: String(cfg.notifyChatId||SUP_NOTIFY_DEFAULT),
          priceSheetId: cfg.priceSheetId||"",
          currency: cfg.currency||"₴",
          price: {
            nameCol: idx2col(cfg.price?.nameCol)??cfg.price?.nameCol??"",
            priceCol: idx2col(cfg.price?.priceCol)??cfg.price?.priceCol??"",
            articleCol: idx2col(cfg.price?.articleCol)??cfg.price?.articleCol??"",
            statusCol: idx2col(cfg.price?.statusCol)??cfg.price?.statusCol??"",
            stockCol: idx2col(cfg.price?.stockCol)??cfg.price?.stockCol??"",
            dataStartRow: cfg.price?.dataStartRow??2,
            searchMode: cfg.price?.searchMode??"standard",
          },
          balanceSheetId: cfg.balanceSheetId||"",
          cbPrefix: cfg.cbPrefix||"",
          cbAuto: !cfg.cbPrefix,
          balanceType: cfg.balanceType||"standard",
          siteSupplierId: cfg.siteSupplierId!=null?String(cfg.siteSupplierId):"",
          warrantyMonths: cfg.warranty&&cfg.warranty.months?String(cfg.warranty.months):"",
          warrantyType: (cfg.warranty&&cfg.warranty.shopType)||"Магазин",
        }));
        setList(arr);
      }
      if(balRes.status==='fulfilled'&&balRes.value.ok) {
        const bm={};
        for(const item of (balRes.value.data||[])) {
          // key = cbPrefix або name.toLowerCase
          bm[item.key] = item.balance;
          bm[item.name] = item.balance;
        }
        setBalances(bm);
      }
    } catch(e){ console.error('Suppliers load error:',e); }
    finally { setLoading(false); }
  },[]);

  useEffect(()=>{ reload(); },[reload]);

  function idx2col(n) {
    if(n==null||n==="") return "";
    if(typeof n==="string") return n; // вже літера
    if(typeof n==="number"&&n>=0&&n<=25) return String.fromCharCode(65+n);
    return "";
  }

  const openNew  = () => { setEditing(supBlank()); setIsNew(true); };
  const openEdit = s  => { setEditing({...s}); setIsNew(false); };
  const close    = () => { setEditing(null); setIsNew(false); };

  const save = async (s) => {
    setSaving(true);
    try {
      // Перетворюємо літери колонок на індекси для API
      const col2idx = c => c?c.charCodeAt(0)-65:null;
      const payload = {
        name:s.name, groupChatId:s.groupChatId, ttnChatId:s.ttnChatId,
        notifyChatId:s.notifyChatId, priceSheetId:s.priceSheetId,
        price:{
          nameCol:col2idx(s.price.nameCol), priceCol:col2idx(s.price.priceCol),
          articleCol:col2idx(s.price.articleCol), statusCol:col2idx(s.price.statusCol),
          stockCol:col2idx(s.price.stockCol), dataStartRow:s.price.dataStartRow,
          searchMode:s.price.searchMode,
        },
        balanceSheetId:s.balanceSheetId, currency:s.currency,
        cbPrefix:s.cbPrefix, balanceType:s.balanceType, active:s.active,
        siteSupplierId:s.siteSupplierId,
      };
      const url    = isNew ? '/api/suppliers' : `/api/suppliers/${s.key}`;
      const method = isNew ? 'POST' : 'PATCH';
      const r = await fetch(url,{method,headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)});
      const d = await r.json();
      if(!d.ok) throw new Error(d.error||'Помилка збереження');
      // Гарантія постачальника — окремо в нашій базі (не в Google-таблиці постачальників), по cbPrefix
      const cbKey = s.cbPrefix || supAutoPrefix(s.key, s.name);
      if (cbKey) {
        try { await fetch(`/api/supplier-warranty/${encodeURIComponent(cbKey)}`,{method:'POST',headers:{'Content-Type':'application/json'},
          body:JSON.stringify({ months: Math.round(Number(String(s.warrantyMonths||"").replace(/[^\d]/g,""))||0), shopType: s.warrantyType||"Магазин" })}); } catch {}
      }
      const wasNew = isNew;
      showMsg(wasNew?'Постачальника додано':'Зміни збережено');
      close();
      await reload();
      // Після додавання нового — пропонуємо надіслати привітання в групу
      if (wasNew && s.groupChatId) setWelcomeFor(s.name);
    } catch(e){ showMsg(e.message,true); }
    finally { setSaving(false); }
  };

  const toggle = async (s) => {
    const orig = s.active;
    setList(prev=>prev.map(p=>p.key===s.key?{...p,active:!p.active}:p));
    try {
      const r = await fetch(`/api/suppliers/${s.key}`,{method:'PATCH',headers:{'Content-Type':'application/json'},body:JSON.stringify({active:!orig})});
      const d = await r.json();
      if(!d.ok) throw new Error(d.error||'Помилка');
    } catch(e){ setList(prev=>prev.map(p=>p.key===s.key?{...p,active:orig}:p)); showMsg(e.message,true); }
  };

  const remove = async (key) => {
    try {
      const r = await fetch(`/api/suppliers/${key}`,{method:'DELETE'});
      const d = await r.json();
      if(!d.ok) throw new Error(d.error||'Помилка видалення');
      setList(prev=>prev.filter(p=>p.key!==key));
      setConfirmKey(null);
      showMsg('Постачальника видалено');
    } catch(e){ showMsg(e.message,true); }
  };

  const activeCount = list.filter(s=>s.active).length;
  const balFor = (s) => {
    return balances[s.cbPrefix]??balances[s.key]??balances[s.name]??null;
  };

  const FormComponent = isMobile ? SupMobileSheet : SupDesktopForm;

  return (
    <div style={{flex:1,display:"flex",flexDirection:"column",minWidth:0,minHeight:0,position:"relative"}}>
      <style>{`
        .supp-card:hover{border-color:var(--border-strong)!important;}
        .supp-input:focus{border-color:var(--accent)!important;box-shadow:0 0 0 3px color-mix(in oklab, var(--accent) 20%, transparent);}
        .supp-input:hover:not(:focus):not(:disabled){border-color:var(--border-strong);}
        select.supp-input option{background:var(--bg-raised);color:var(--fg-primary);}
        @keyframes supPanelIn{from{transform:translateX(100%)}to{transform:translateX(0)}}
        @keyframes supFade{from{opacity:0}to{opacity:1}}
        @keyframes supSlideUp{from{transform:translateY(100%)}to{transform:translateY(0)}}
      `}</style>

      {/* Toolbar */}
      {!isMobile && (
        <div style={{padding:"16px 24px",borderBottom:"1px solid var(--border-subtle)",display:"flex",alignItems:"center",gap:14,flexShrink:0}}>
          <span style={{fontSize:13,color:"var(--fg-secondary)"}}>
            {list.length} {pluralSup(list.length)} · <span style={{color:"var(--credit)"}}>{activeCount} активних</span>
          </span>
          <div style={{flex:1}}/>
          <Button variant="primary" size="md" leftIcon="plus" onClick={openNew}>Додати постачальника</Button>
        </div>
      )}

      {/* Mobile sub-toolbar */}
      {isMobile && (
        <div style={{display:"flex",alignItems:"center",gap:10,padding:"12px 16px 4px"}}>
          <span style={{flex:1,fontSize:12,color:"var(--fg-muted)"}}>
            {list.length} всього · <span style={{color:"var(--credit)"}}>{activeCount} активних</span>
          </span>
          <button onClick={openNew} style={{height:34,padding:"0 14px",border:0,background:"var(--accent)",color:"#fff",borderRadius:9,cursor:"pointer",fontSize:13,fontWeight:600,fontFamily:"inherit",display:"inline-flex",alignItems:"center",gap:7}}>
            <Icon name="plus" size={15}/> Додати
          </button>
        </div>
      )}

      {/* Content */}
      {loading ? (
        <div style={{flex:1,display:"flex",alignItems:"center",justifyContent:"center",color:"var(--fg-muted)",fontSize:13}}>
          Завантаження…
        </div>
      ) : list.length===0 ? (
        <SupEmpty onAdd={openNew} isMobile={isMobile}/>
      ) : (
        <div style={{flex:1,overflow:"auto",padding:isMobile?"12px 16px 88px":24}}>
          <div style={isMobile
            ? {display:"flex",flexDirection:"column",gap:12}
            : {display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(340px, 1fr))",gap:16}
          }>
            {list.map(s=>isMobile ? (
              <SupCardMobile key={s.key} s={s} onEdit={openEdit} onToggle={toggle} onWelcome={()=>setWelcomeFor(s.name)}
                balance={balFor(s)}
                confirming={confirmKey===s.key} onConfirmOpen={setConfirmKey}
                onConfirmCancel={()=>setConfirmKey(null)} onDelete={()=>remove(s.key)}/>
            ) : (
              <SupCard key={s.key} s={s} onEdit={openEdit} onToggle={toggle} onWelcome={()=>setWelcomeFor(s.name)}
                balance={balFor(s)}
                confirming={confirmKey===s.key} onConfirmOpen={setConfirmKey}
                onConfirmCancel={()=>setConfirmKey(null)} onDelete={()=>remove(s.key)}/>
            ))}
          </div>
        </div>
      )}

      {/* Form */}
      {editing && (
        <FormComponent initial={editing} isNew={isNew}
          existingKeys={list.map(s=>s.key).filter(k=>isNew||k!==editing.key)}
          onCancel={close} onSave={save} saving={saving}/>
      )}

      {/* Welcome modal */}
      {welcomeFor && (
        <SupWelcomeModal supplierKey={welcomeFor} onClose={()=>setWelcomeFor(null)}
          onResult={(ok,msg)=>showMsg(msg,!ok)}/>
      )}

      {/* Toast */}
      {toast && (
        <div style={{position:"absolute",bottom:isMobile?96:24,left:"50%",transform:"translateX(-50%)",
          padding:"10px 18px",borderRadius:9,fontSize:13,fontWeight:500,whiteSpace:"nowrap",zIndex:100,
          background:toast.err?"rgba(244,63,94,.14)":"rgba(16,185,129,.14)",
          border:`1px solid ${toast.err?"rgba(244,63,94,.3)":"rgba(16,185,129,.3)"}`,
          color:toast.err?"var(--danger)":"var(--credit)"}}>
          {toast.msg}
        </div>
      )}
    </div>
  );
}

Object.assign(window,{Suppliers});
