/* Bilermen - Admin panel.
   Look & feel modelled on the original admin (dark sidebar, white page head with
   a Save button top-right, EN/RU tabs, card grids with Edit / Delete / + Add,
   full-page editors with Cancel / Save) - but fully working.

   How saving works on a static site (no server/database):
   • "Save" / "Save changes" stores the whole content in THIS browser and the site
     immediately shows it (preview that survives reloads).
   • "Publish" downloads an updated data.js - replace it in your deployed site and
     re-publish so every visitor sees the changes. (There is no server to save to,
     so this download is the only way to make edits live for everyone.)

   Interface language follows the EN/RU switch: it changes both the panel language
   and which language's content you are editing. */

const AdminUI = (function () {
  const { useState, useRef } = React;

  const DRAFT_KEY = 'bilermen_content_v3';
  const PASS = 'bilermen2026'; // change here, then Publish

  /* ---------------------------------------------------------- UI strings */
  const STR = {
    en: {
      panel: 'Admin panel', login: 'Admin Panel', loginSub: 'Sign in to manage the website content.',
      password: 'Password', signin: 'Sign in', wrongPass: 'Wrong password.',
      save: 'Save changes', saved: 'Saved ✓', add: 'Add', edit: 'Edit', del: 'Delete',
      cancel: 'Cancel', publish: 'Publish', openSite: 'Open site →',
      publishHint: 'Saved in this browser. Click Publish to download data.js and make it live for everyone.',
      published: 'data.js downloaded - replace it on your server and re-publish.',
      confirmDel: 'Delete this item permanently?', empty: 'Nothing yet. Click “Add”.',
      moveUp: 'Up', moveDown: 'Down', dup: 'Duplicate',
      nav: { dashboard: 'Dashboard', hero: 'Hero & Intro', services: 'Services', sectors: 'Sectors', advantages: 'Advantages', news: 'News', partners: 'Partners', contact: 'Contact Info', branding: 'Branding', legal: 'Legal', submissions: 'Submissions' },
      meta: {
        dashboard: ['Dashboard', 'Overview of your website content.'],
        hero: ['Hero & Intro', 'Homepage hero and the “About Bilermen” section.'],
        services: ['Services', 'Service cards, their detail pages and photos.'],
        sectors: ['Sectors', 'Priority sectors, their detail pages and photos.'],
        advantages: ['Advantages', 'The five advantages on the About page.'],
        news: ['News', 'Articles - add, edit, or delete posts.'],
        partners: ['Partners', 'Logos in the “Trusted by” carousel.'],
        contact: ['Contact information', 'Phone, email, address, LinkedIn - used in the footer and contact page.'],
        branding: ['Logo & favicon', 'Site logo and browser-tab icon.'],
        legal: ['Legal / Privacy', 'Edit the Privacy Policy page - last-updated date, intro, sections, and terms.'],
        submissions: ['Submissions', 'Where form submissions go.'],
      },
      addItem: { services: '+ Add service', sectors: '+ Add sector', advantages: '+ Add advantage', news: '+ New article', partners: '+ Add partner' },
      editTitle: { services: 'service', sectors: 'sector', advantages: 'advantage', news: 'article', partners: 'partner' },
      subsBody: 'The form on the Contact page sends submissions through Web3Forms. Every inquiry is delivered to the email linked to your Web3Forms key and is available in your Web3Forms dashboard at web3forms.com. To change the recipient address, update it in your Web3Forms account (no code change needed).',
      brandLogo: 'Site logo', brandLogoHint: 'Shown in the header and footer. SVG or transparent PNG works best.',
      brandFav: 'Favicon (tab icon)', brandFavHint: 'Small icon in the browser tab. A square SVG or PNG.',
      logoFile: 'Logo file', altText: 'Alt text', favFile: 'Icon file',
      latestNews: 'Latest news', noNews: 'No news yet.',
      counts: { services: 'Services', sectors: 'Sectors', news: 'News', partners: 'Partners' },
    },
    ru: {
      panel: 'Админ-панель', login: 'Админ-панель', loginSub: 'Войдите, чтобы управлять содержимым сайта.',
      password: 'Пароль', signin: 'Войти', wrongPass: 'Неверный пароль.',
      save: 'Сохранить', saved: 'Сохранено ✓', add: 'Добавить', edit: 'Изменить', del: 'Удалить',
      cancel: 'Отмена', publish: 'Опубликовать', openSite: 'Открыть сайт →',
      publishHint: 'Сохранено в этом браузере. Нажмите «Опубликовать», чтобы скачать data.js и показать правки всем.',
      published: 'data.js скачан - замените им файл на сервере и опубликуйте заново.',
      confirmDel: 'Удалить эту запись безвозвратно?', empty: 'Пока пусто. Нажмите «Добавить».',
      moveUp: 'Вверх', moveDown: 'Вниз', dup: 'Дублировать',
      nav: { dashboard: 'Обзор', hero: 'Главный экран', services: 'Услуги', sectors: 'Сектора', advantages: 'Преимущества', news: 'Новости', partners: 'Партнёры', contact: 'Контакты', branding: 'Логотип и иконка', legal: 'Политика', submissions: 'Заявки' },
      meta: {
        dashboard: ['Обзор', 'Сводка по содержимому сайта.'],
        hero: ['Главный экран и «О нас»', 'Первый экран сайта и блок «О Bilermen».'],
        services: ['Услуги', 'Карточки услуг, их страницы и фотографии.'],
        sectors: ['Сектора', 'Приоритетные сектора, их страницы и фотографии.'],
        advantages: ['Преимущества', 'Пять преимуществ на странице «О нас».'],
        news: ['Новости', 'Статьи - добавление, изменение, удаление.'],
        partners: ['Партнёры', 'Логотипы в блоке «Нам доверяют».'],
        contact: ['Контактная информация', 'Телефон, email, адрес, LinkedIn - для подвала и страницы контактов.'],
        branding: ['Логотип и иконка', 'Логотип сайта и иконка вкладки.'],
        legal: ['Политика конфиденциальности', 'Редактирование страницы Политики - дата обновления, вступление, разделы, условия.'],
        submissions: ['Заявки', 'Куда приходят заявки с сайта.'],
      },
      addItem: { services: '+ Добавить услугу', sectors: '+ Добавить сектор', advantages: '+ Добавить преимущество', news: '+ Новая статья', partners: '+ Добавить партнёра' },
      editTitle: { services: 'услугу', sectors: 'сектор', advantages: 'преимущество', news: 'статью', partners: 'партнёра' },
      subsBody: 'Форма на странице «Контакты» отправляет заявки через сервис Web3Forms. Каждое обращение приходит на email, привязанный к вашему ключу Web3Forms, и доступно в личном кабинете на web3forms.com. Чтобы сменить адрес получателя - измените его в кабинете Web3Forms (править код не нужно).',
      brandLogo: 'Логотип сайта', brandLogoHint: 'Показывается в шапке и подвале. Лучше всего SVG или PNG с прозрачным фоном.',
      brandFav: 'Favicon (иконка вкладки)', brandFavHint: 'Маленькая иконка во вкладке браузера. Квадратное изображение SVG/PNG.',
      logoFile: 'Файл логотипа', altText: 'Альтернативный текст (alt)', favFile: 'Файл иконки',
      latestNews: 'Последние новости', noNews: 'Новостей пока нет.',
      counts: { services: 'Услуги', sectors: 'Сектора', news: 'Новости', partners: 'Партнёры' },
    },
  };

  /* field schema (labels bilingual). type: text|textarea|select|image|list|pairs|stats */
  const FIELD_LABELS = {
    no: ['Number (e.g. 01)', 'Номер (например, 01)'],
    slug: ['URL slug (latin)', 'Slug (латиницей)'],
    date: ['Date (YYYY-MM-DD)', 'Дата (ГГГГ-ММ-ДД)'],
    title: ['Title', 'Название'], name: ['Name', 'Название'],
    short: ['Short description', 'Краткое описание'],
    hero: ['Page subtitle', 'Подзаголовок на странице'],
    lede: ['Intro paragraph', 'Вводный абзац'],
    deliverables: ['What we deliver', 'Что мы предоставляем'],
    examples: ['Engagement examples (optional)', 'Примеры проектов (необязательно)'],
    tag: ['Tag (e.g. Energy)', 'Тег (например, Энергетика)'],
    opportunity: ['Opportunity (paragraph)', 'Возможности (абзац)'],
    valueAdd: ['How Bilermen adds value', 'Как Bilermen добавляет ценность'],
    stats: ['Stats / facts (optional)', 'Цифры/факты (необязательно)'],
    deep: ['Detailed description', 'Подробное описание'],
    category: ['Category', 'Категория'],
    dek: ['Subtitle', 'Подзаголовок'],
    body: ['Body (paragraphs split by a blank line)', 'Текст (абзацы - через пустую строку)'],
    image: ['Photo', 'Фото'],
    group: ['Lane', 'Лента'],
    url: ['Website link', 'Ссылка на сайт'],
    logo: ['Logo (upload an image; if empty, the built-in brand logo is used)', 'Логотип (загрузите изображение; если пусто - встроенный логотип)'],
    eyebrow: ['Eyebrow (small text above title)', 'Надпись над заголовком'],
    subtle: ['Subtitle in brackets', 'Подпись в скобках'],
    gateway: ['Gateway line', 'Слоган'],
    subtitle: ['Description', 'Описание'],
    cta1: ['Primary button', 'Кнопка 1'], cta2: ['Secondary button', 'Кнопка 2'],
    address: ['Address', 'Адрес'], addressUrl: ['Map link', 'Ссылка на карту'],
    email: ['Email', 'Email'], phone: ['Phone', 'Телефон'], phone2: ['Phone 2', 'Телефон 2'],
    linkedin: ['LinkedIn (link)', 'LinkedIn (ссылка)'], linkedinHandle: ['LinkedIn (display name)', 'LinkedIn (имя)'],
  };
  const F = (k, t, opts) => ({ k, t, bi: !!(opts && opts.bi), options: opts && opts.options, neutral: !!(opts && opts.neutral) });
  const SCHEMA = {
    services: { listKey: 'SERVICES', titleKey: 'title', fields: [F('no','text',{neutral:1}),F('slug','text',{neutral:1}),F('title','text',{bi:1}),F('short','text',{bi:1}),F('hero','text',{bi:1}),F('lede','textarea',{bi:1}),F('deliverables','list',{bi:1}),F('examples','pairs',{bi:1}),F('image','image',{bi:1})] },
    sectors:  { listKey: 'SECTORS', titleKey: 'title', fields: [F('slug','text',{neutral:1}),F('tag','text',{bi:1}),F('title','text',{bi:1}),F('short','text',{bi:1}),F('opportunity','textarea',{bi:1}),F('valueAdd','list',{bi:1}),F('stats','stats',{neutral:1}),F('image','image',{bi:1})] },
    advantages:{ listKey: 'ADVANTAGES', titleKey: 'title', fields: [F('no','text',{neutral:1}),F('slug','text',{neutral:1}),F('title','text',{bi:1}),F('short','text',{bi:1}),F('deep','textarea',{bi:1}),F('image','image',{neutral:1})] },
    news:     { listKey: 'NEWS', titleKey: 'title', fields: [F('slug','text',{neutral:1}),F('date','text',{neutral:1}),F('category','text',{bi:1}),F('title','text',{bi:1}),F('dek','textarea',{bi:1}),F('body','textarea',{bi:1}),F('image','image',{neutral:1})] },
    partners: { listKey: 'PARTNERS', titleKey: 'name', fields: [F('name','text',{neutral:1}),F('group','select',{options:[['development','Partners (top lane) / Партнёры (верхняя)'],['private','Private sector (bottom) / Частный сектор (нижняя)']]}),F('url','text',{neutral:1}),F('logo','image',{neutral:1})] },
  };
  const HERO_FIELDS = [F('eyebrow','text',{bi:1}),F('title','text',{bi:1}),F('subtle','text',{bi:1}),F('gateway','text',{bi:1}),F('subtitle','text',{bi:1}),F('cta1','text',{bi:1}),F('cta2','text',{bi:1}),F('image','image',{bi:1})];
  const CONTACT_FIELDS = [F('title','text',{bi:1}),F('address','textarea',{bi:1}),F('addressUrl','text',{neutral:1}),F('email','text',{neutral:1}),F('phone','text',{neutral:1}),F('phone2','text',{neutral:1}),F('linkedin','text',{neutral:1}),F('linkedinHandle','text',{neutral:1})];

  /* ------------------------------------------------------------- styling */
  const C = { teal: '#006D77', ink: '#0A1F26', sidebar: '#0A1F26', line: '#dfe3e3', soft: '#f4f6f6', red: '#b3261e', muted: '#6b7a7c' };
  const sInput = { width: '100%', padding: '10px 12px', border: '1px solid ' + C.line, borderRadius: 8, font: '400 14px/1.5 system-ui, sans-serif', boxSizing: 'border-box', background: '#fff', color: C.ink };
  const sLabel = { display: 'block', font: '600 11px/1.4 system-ui, sans-serif', letterSpacing: '0.6px', textTransform: 'uppercase', color: C.muted, marginBottom: 6, marginTop: 16 };
  const sBtn = { padding: '10px 18px', borderRadius: 8, border: '1px solid ' + C.teal, background: C.teal, color: '#fff', font: '600 13px system-ui, sans-serif', cursor: 'pointer' };
  const sBtnGhost = { padding: '10px 16px', borderRadius: 8, border: '1px solid ' + C.line, background: '#fff', color: C.ink, font: '600 13px system-ui, sans-serif', cursor: 'pointer' };
  const sBtnSm = { padding: '6px 13px', borderRadius: 7, border: '1px solid ' + C.line, background: '#fff', color: C.ink, font: '600 12px system-ui, sans-serif', cursor: 'pointer' };
  const sBtnTiny = { padding: '4px 10px', borderRadius: 6, border: '1px solid ' + C.line, background: '#fff', color: C.ink, font: '600 12px system-ui, sans-serif', cursor: 'pointer' };
  const sCard = { border: '1px solid ' + C.line, borderRadius: 12, background: '#fff', padding: 20, marginBottom: 14 };
  const clone = (o) => JSON.parse(JSON.stringify(o));
  const fileToDataUrl = (file, cb) => { const r = new FileReader(); r.onload = () => cb(r.result); r.readAsDataURL(file); };

  /* page head - title + sub + action button(s) top-right (like original) */
  function PageHead({ title, sub, action }) {
    return (
      <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16, marginBottom: 18, flexWrap: 'wrap' }}>
        <div>
          <h2 style={{ font: '700 26px system-ui', color: C.ink, margin: '0 0 4px' }}>{title}</h2>
          {sub && <p style={{ color: C.muted, font: '14px system-ui', margin: 0 }}>{sub}</p>}
        </div>
        {action && <div style={{ display: 'flex', gap: 8 }}>{action}</div>}
      </div>
    );
  }
  function LangTabs({ lang, setLang }) {
    return (
      <div style={{ display: 'inline-flex', background: '#fff', border: '1px solid ' + C.line, borderRadius: 10, padding: 3, marginBottom: 18 }}>
        {[['en', 'EN · English'], ['ru', 'RU · Русский']].map(([v, lbl]) => (
          <button key={v} onClick={() => setLang(v)}
            style={{ padding: '7px 15px', borderRadius: 8, border: 0, cursor: 'pointer', font: '600 13px system-ui', background: lang === v ? C.teal : 'transparent', color: lang === v ? '#fff' : C.ink }}>
            {lbl}
          </button>
        ))}
      </div>
    );
  }

  /* ----------------------------------------------------------- field UI */
  function Field({ field, item, lang, onChange }) {
    const labelPair = FIELD_LABELS[field.k] || [field.k, field.k];
    const label = labelPair[lang === 'ru' ? 1 : 0];
    const key = field.bi ? field.k + (lang === 'ru' ? '_ru' : '') : field.k;
    const val = item[key];
    const set = (v) => onChange(key, v);
    if (field.t === 'text') return (<div><label style={sLabel}>{label}</label><input style={sInput} value={val || ''} onChange={e => set(e.target.value)} /></div>);
    if (field.t === 'textarea') return (<div><label style={sLabel}>{label}</label><textarea style={{ ...sInput, minHeight: 96, resize: 'vertical' }} value={val || ''} onChange={e => set(e.target.value)} /></div>);
    if (field.t === 'select') return (<div><label style={sLabel}>{label}</label><select style={sInput} value={val || ''} onChange={e => set(e.target.value)}>{field.options.map(([v, l]) => <option key={v} value={v}>{l}</option>)}</select></div>);
    if (field.t === 'image') return <ImageField label={label} value={val} onChange={set} />;
    if (field.t === 'list') return <ListField label={label} arr={val || []} onChange={set} />;
    if (field.t === 'pairs') return <PairsField label={label} arr={val || []} onChange={set} lang={lang} />;
    if (field.t === 'stats') return <StatsField label={label} stats={item[field.k] || []} lang={lang} onChange={v => onChange(field.k, v)} />;
    return null;
  }

  function ImageField({ label, value, onChange }) {
    const inputRef = useRef(null);
    return (
      <div>
        <label style={sLabel}>{label}</label>
        <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}>
          {value
            ? <img src={value} alt="" style={{ width: 110, height: 72, objectFit: 'cover', borderRadius: 8, border: '1px solid ' + C.line, flex: '0 0 auto', background: '#eee' }} onError={e => { e.target.style.opacity = 0.25; }} />
            : <div style={{ width: 110, height: 72, borderRadius: 8, border: '1px dashed ' + C.line, flex: '0 0 auto', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#aaa', fontSize: 11 }}>-</div>}
          <div style={{ flex: 1 }}>
            <input style={sInput} placeholder="https://…  or  assets/name.jpg" value={value || ''} onChange={e => onChange(e.target.value)} />
            <div style={{ marginTop: 8, display: 'flex', gap: 8 }}>
              <button style={sBtnTiny} onClick={() => inputRef.current && inputRef.current.click()}>Upload / Загрузить</button>
              {value && <button style={sBtnTiny} onClick={() => onChange('')}>Clear</button>}
            </div>
            <input ref={inputRef} type="file" accept="image/*" style={{ display: 'none' }} onChange={e => { const f = e.target.files[0]; if (f) fileToDataUrl(f, onChange); }} />
          </div>
        </div>
      </div>
    );
  }
  function ListField({ label, arr, onChange }) {
    const rows = Math.max(arr.length, 1);
    const setRow = (i, v) => { const n = arr.slice(); while (n.length <= i) n.push(''); n[i] = v; onChange(n); };
    return (
      <div>
        <label style={sLabel}>{label}</label>
        {Array.from({ length: rows }).map((_, i) => (
          <div key={i} style={{ display: 'flex', gap: 6, marginBottom: 6 }}>
            <input style={{ ...sInput, flex: 1 }} value={arr[i] || ''} onChange={e => setRow(i, e.target.value)} />
            <button style={sBtnTiny} onClick={() => { const n = arr.slice(); n.splice(i, 1); onChange(n); }}>✕</button>
          </div>
        ))}
        <button style={sBtnTiny} onClick={() => onChange([...arr, ''])}>+ Add / Добавить</button>
      </div>
    );
  }
  function PairsField({ label, arr, onChange }) {
    const list = arr || [];
    const set = (i, f, v) => { const n = clone(list); while (n.length <= i) n.push({ client: '', work: '' }); n[i][f] = v; onChange(n); };
    return (
      <div>
        <label style={sLabel}>{label}</label>
        {list.map((p, i) => (
          <div key={i} style={{ border: '1px solid ' + C.line, borderRadius: 8, padding: 8, marginBottom: 8 }}>
            <div style={{ display: 'flex', justifyContent: 'flex-end' }}><button style={sBtnTiny} onClick={() => { const n = clone(list); n.splice(i, 1); onChange(n); }}>✕</button></div>
            <input style={{ ...sInput, marginBottom: 5 }} placeholder="Client / Клиент" value={p.client || ''} onChange={e => set(i, 'client', e.target.value)} />
            <input style={sInput} placeholder="Work / Работа" value={p.work || ''} onChange={e => set(i, 'work', e.target.value)} />
          </div>
        ))}
        <button style={sBtnTiny} onClick={() => onChange([...list, { client: '', work: '' }])}>+ Add / Добавить</button>
      </div>
    );
  }
  function StatsField({ label, stats, lang, onChange }) {
    const list = stats || [];
    const numKey = lang === 'ru' ? 'num_ru' : 'num';
    const lblKey = lang === 'ru' ? 'lbl_ru' : 'lbl';
    const set = (i, f, v) => { const n = clone(list); n[i][f] = v; onChange(n); };
    return (
      <div>
        <label style={sLabel}>{label}</label>
        {list.map((st, i) => (
          <div key={i} style={{ display: 'flex', gap: 6, marginBottom: 6 }}>
            <input style={{ ...sInput, flex: '0 0 90px' }} placeholder={lang === 'ru' ? '4-е' : '4th'} value={st[numKey] || ''} onChange={e => set(i, numKey, e.target.value)} />
            <input style={{ ...sInput, flex: 1 }} placeholder={lang === 'ru' ? 'Подпись' : 'Label'} value={st[lblKey] || ''} onChange={e => set(i, lblKey, e.target.value)} />
            <button style={sBtnTiny} onClick={() => { const n = clone(list); n.splice(i, 1); onChange(n); }}>✕</button>
          </div>
        ))}
        <button style={sBtnTiny} onClick={() => onChange([...list, { num: '', num_ru: '', lbl: '', lbl_ru: '' }])}>+ Add / Добавить</button>
      </div>
    );
  }
  function FieldList({ fields, item, lang, onChange }) {
    return <div>{fields.map(f => <Field key={f.k} field={f} item={item} lang={lang} onChange={onChange} />)}</div>;
  }

  /* ------------------------------------------------ list section (cards) */
  function ListSection({ secKey, content, commit, lang, T }) {
    const def = SCHEMA[secKey];
    const list = content[def.listKey] || [];
    const [editing, setEditing] = useState(null); // {index, draft} or null
    const dragIdx = useRef(-1);
    const titleOf = (it) => it[def.titleKey] || it[def.titleKey + '_ru'] || '(-)';

    if (editing) {
      const onChange = (k, v) => setEditing(e => ({ ...e, draft: { ...e.draft, [k]: v } }));
      const [editLang, setEditLang] = [lang, () => {}]; // editor follows global lang
      const saveItem = () => {
        const n = list.slice();
        if (editing.index === -1) n.push(editing.draft); else n[editing.index] = editing.draft;
        commit({ ...content, [def.listKey]: n });
        setEditing(null);
      };
      return (
        <div>
          <PageHead title={(editing.index === -1 ? (lang === 'ru' ? 'Добавить ' : 'Add ') : (lang === 'ru' ? 'Изменить ' : 'Edit ')) + T.editTitle[secKey]}
            sub={editing.draft.slug ? 'slug: ' + editing.draft.slug : ''}
            action={<><button style={sBtnGhost} onClick={() => setEditing(null)}>{T.cancel}</button><button style={sBtn} onClick={saveItem}>{T.save}</button></>} />
          <LangTabs lang={lang} setLang={(v) => window.__setAdminLang && window.__setAdminLang(v)} />
          <div style={sCard}><FieldList fields={def.fields} item={editing.draft} lang={lang} onChange={onChange} /></div>
          <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
            <button style={sBtnGhost} onClick={() => setEditing(null)}>{T.cancel}</button>
            <button style={sBtn} onClick={saveItem}>{T.save}</button>
          </div>
        </div>
      );
    }

    const blank = () => {
      const b = {};
      def.fields.forEach(f => {
        if (f.t === 'list' || f.t === 'pairs') { b[f.k] = []; if (f.bi) b[f.k + '_ru'] = []; }
        else if (f.t === 'stats') b[f.k] = [];
        else if (f.t === 'select') b[f.k] = f.options[0][0];
        else { b[f.k] = ''; if (f.bi) b[f.k + '_ru'] = ''; }
      });
      if ('slug' in b) b.slug = 'new-' + Date.now();
      return b;
    };
    const remove = (i) => { if (!confirm(T.confirmDel)) return; const n = list.slice(); n.splice(i, 1); commit({ ...content, [def.listKey]: n }); };
    const move = (i, d) => { const j = i + d; if (j < 0 || j >= list.length) return; const n = list.slice(); const tmp = n[i]; n[i] = n[j]; n[j] = tmp; commit({ ...content, [def.listKey]: n }); };
    const dup = (i) => { const c = clone(list[i]); if (c.slug) c.slug = c.slug + '-copy'; const n = list.slice(); n.splice(i + 1, 0, c); commit({ ...content, [def.listKey]: n }); };
    const reorder = (from, to) => { if (from == null || to == null || from === to || from < 0 || to < 0 || from >= list.length || to >= list.length) return; const n = list.slice(); const [m] = n.splice(from, 1); n.splice(to, 0, m); commit({ ...content, [def.listKey]: n }); };

    const thumb = (it) => {
      if (secKey === 'partners') {
        const hasLogo = it.logo && String(it.logo).trim();
        const svg = (!hasLogo && typeof PartnerLogoSvg === 'function') ? PartnerLogoSvg({ name: it.name }) : null;
        return (
          <div style={{ width: 104, height: 56, flex: '0 0 auto', background: '#fff', border: '1px solid ' + C.line, borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden', padding: 8 }}>
            {hasLogo ? <img src={it.logo} alt="" style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain' }} />
              : svg ? svg
              : <span style={{ font: '700 13px system-ui', color: C.ink, textAlign: 'center' }}>{it.name}</span>}
          </div>
        );
      }
      return it.image ? <img src={it.image} alt="" style={{ width: 84, height: 60, objectFit: 'cover', borderRadius: 8, flex: '0 0 auto', background: '#eee' }} onError={e => { e.target.style.opacity = .2; }} /> : null;
    };

    const renderCard = (it, i) => (
      <div key={i} draggable
        onDragStart={(e) => { dragIdx.current = i; e.dataTransfer.effectAllowed = 'move'; }}
        onDragOver={(e) => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; }}
        onDrop={(e) => { e.preventDefault(); reorder(dragIdx.current, i); dragIdx.current = -1; }}
        style={{ ...sCard, marginBottom: 0, display: 'flex', gap: 12, alignItems: 'center', cursor: 'grab' }}>
        <span style={{ flex: '0 0 auto', color: C.muted, fontSize: 15, lineHeight: 1, cursor: 'grab', userSelect: 'none' }} title={lang === 'ru' ? 'Перетащите, чтобы изменить порядок' : 'Drag to reorder'}>⣿</span>
        {thumb(it)}
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ font: '600 15px system-ui', color: C.ink, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{titleOf(it)}</div>
          <div style={{ font: '12px system-ui', color: C.muted, marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{it.slug || it.url || ''}</div>
          <div style={{ display: 'flex', gap: 6, marginTop: 10, flexWrap: 'wrap' }}>
            <button style={sBtnSm} onClick={() => setEditing({ index: i, draft: clone(it) })}>{T.edit}</button>
            <button style={{ ...sBtnSm, color: C.red, borderColor: '#e7c3c0' }} onClick={() => remove(i)}>{T.del}</button>
            <button style={sBtnTiny} onClick={() => dup(i)}>{T.dup}</button>
          </div>
        </div>
      </div>
    );

    const head = (
      <PageHead title={T.meta[secKey][0]} sub={T.meta[secKey][1]}
        action={<button style={sBtn} onClick={() => setEditing({ index: -1, draft: blank() })}>{T.addItem[secKey]}</button>} />
    );

    if (secKey === 'partners') {
      const groups = [
        ['development', lang === 'ru' ? 'Международные партнёры по развитию - верхняя лента' : 'International Development Partners - top lane'],
        ['private', lang === 'ru' ? 'Частный сектор и мировой бизнес - нижняя лента' : 'Private Sector & Global Business - bottom lane'],
      ];
      return (
        <div>
          {head}
          <div style={{ font: '12px system-ui', color: C.muted, margin: '0 0 16px' }}>{lang === 'ru' ? 'Перетаскивайте логотипы мышью, чтобы менять порядок. Лента (группа) задаётся полем «Лента» при редактировании логотипа.' : 'Drag logos to reorder. The lane (group) is set by the “Lane” field when editing a logo.'}</div>
          {groups.map(([g, label]) => {
            const inGroup = list.map((it, i) => [it, i]).filter(([it]) => (g === 'development' ? it.group === 'development' : it.group !== 'development'));
            return (
              <div key={g} style={{ marginBottom: 26 }}>
                <div style={{ font: '700 11px system-ui', letterSpacing: 1, textTransform: 'uppercase', color: C.teal, margin: '0 0 12px', paddingBottom: 8, borderBottom: '1px solid ' + C.line }}>{label} <span style={{ color: C.muted, fontWeight: 400 }}>· {inGroup.length}</span></div>
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 14 }}>
                  {inGroup.map(([it, i]) => renderCard(it, i))}
                </div>
                {inGroup.length === 0 && <div style={{ color: '#888', font: '13px system-ui' }}>{T.empty}</div>}
              </div>
            );
          })}
        </div>
      );
    }

    return (
      <div>
        {head}
        <div style={{ display: 'grid', gridTemplateColumns: secKey === 'news' ? '1fr' : 'repeat(2, 1fr)', gap: 14 }}>
          {list.map((it, i) => renderCard(it, i))}
        </div>
        {list.length === 0 && <div style={{ color: '#888', font: '14px system-ui' }}>{T.empty}</div>}
      </div>
    );
  }

  /* --------------------------------------------- object sections (hero…) */
  function HeroIntroSection({ content, setContent, persist, lang, T }) {
    const hero = content.HERO || {}; const intro = content.INTRO || {};
    const setHero = (k, v) => setContent({ ...content, HERO: { ...hero, [k]: v } });
    const setIntro = (k, v) => setContent({ ...content, INTRO: { ...intro, [k]: v } });
    const [saved, setSaved] = useState(false);
    const onSave = () => { persist(); setSaved(true); setTimeout(() => setSaved(false), 1800); };
    return (
      <div>
        <PageHead title={T.meta.hero[0]} sub={T.meta.hero[1]}
          action={<button style={sBtn} onClick={onSave}>{saved ? T.saved : T.save}</button>} />
        <LangTabs lang={lang} setLang={(v) => window.__setAdminLang(v)} />
        <div style={sCard}>
          <h3 style={{ font: '700 15px system-ui', color: C.ink, margin: '0 0 4px' }}>{lang === 'ru' ? 'Главный экран' : 'Hero section'}</h3>
          <FieldList fields={HERO_FIELDS} item={hero} lang={lang} onChange={setHero} />
        </div>
        <div style={sCard}>
          <h3 style={{ font: '700 15px system-ui', color: C.ink, margin: '0 0 4px' }}>{lang === 'ru' ? 'Блок «О Bilermen»' : 'About Bilermen'}</h3>
          <Field field={F('image', 'image', { bi: 1 })} item={intro} lang={lang} onChange={setIntro} />
        </div>
      </div>
    );
  }
  function ContactSection({ content, setContent, persist, lang, T }) {
    const c = (content.CONTACTS && content.CONTACTS[0]) || {};
    const setC = (k, v) => { const arr = (content.CONTACTS || [{}]).slice(); arr[0] = { ...arr[0], [k]: v }; setContent({ ...content, CONTACTS: arr }); };
    const [saved, setSaved] = useState(false);
    const onSave = () => { persist(); setSaved(true); setTimeout(() => setSaved(false), 1800); };
    return (
      <div>
        <PageHead title={T.meta.contact[0]} sub={T.meta.contact[1]} action={<button style={sBtn} onClick={onSave}>{saved ? T.saved : T.save}</button>} />
        <LangTabs lang={lang} setLang={(v) => window.__setAdminLang(v)} />
        <div style={sCard}><FieldList fields={CONTACT_FIELDS} item={c} lang={lang} onChange={setC} /></div>
      </div>
    );
  }
  function LegalSection({ content, setContent, commit, persist, lang, T }) {
    const sfx = lang === 'ru' ? '_ru' : '';
    const legal = content.LEGAL || { sections: [] };
    const [saved, setSaved] = useState(false);
    const setLegal = (patch) => setContent({ ...content, LEGAL: { ...legal, ...patch } });
    const setField = (k, v) => setLegal({ [k + sfx]: v });
    const setSection = (i, key, v) => {
      const secs = (legal.sections || []).map((s, j) => (j === i ? { ...s, [key + sfx]: v } : s));
      setLegal({ sections: secs });
    };
    /* structural changes (add/delete/reorder) commit immediately - same behaviour
       as Services/News lists; text edits still go through the Save button */
    const commitSections = (secs) => commit({ ...content, LEGAL: { ...legal, sections: secs } });
    const addSection = () => commitSections([...(legal.sections || []), { h: '', h_ru: '', body: '', body_ru: '' }]);
    const removeSection = (i) => {
      if (!confirm(T.confirmDel)) return;
      commitSections((legal.sections || []).filter((_, j) => j !== i));
    };
    const moveSection = (i, d) => {
      const secs = (legal.sections || []).slice();
      const j = i + d;
      if (j < 0 || j >= secs.length) return;
      const tmp = secs[i]; secs[i] = secs[j]; secs[j] = tmp;
      commitSections(secs);
    };
    const onSave = () => { persist(); setSaved(true); setTimeout(() => setSaved(false), 1800); };
    const L = lang === 'ru'
      ? { updated: 'Дата обновления', intro: 'Вступление', sectionsTitle: 'Разделы', heading: 'Заголовок раздела', text: 'Текст (абзацы разделяйте пустой строкой)', termsTitle: 'Заголовок «Условия использования»', termsBody: 'Текст условий', hint: 'Подсказка: {email} автоматически заменяется на контактный email. Язык переключайте сверху (EN/RU).', addSection: '+ Добавить раздел', section: 'Раздел', secHint: 'Заполните заголовок и текст на обоих языках (EN/RU - переключатель сверху).' }
      : { updated: 'Last updated date', intro: 'Intro paragraph', sectionsTitle: 'Sections', heading: 'Section heading', text: 'Text (separate paragraphs with a blank line)', termsTitle: 'Terms title', termsBody: 'Terms body', hint: 'Tip: {email} is replaced automatically with your contact email. Switch language with EN/RU above.', addSection: '+ Add section', section: 'Section', secHint: 'Fill in the heading and text in both languages (EN/RU switch above).' };
    const lbl = { font: '600 12px system-ui', color: C.muted, display: 'block', margin: '0 0 6px' };
    return (
      <div>
        <PageHead title={T.meta.legal[0]} sub={T.meta.legal[1]}
          action={<button style={sBtn} onClick={onSave}>{saved ? T.saved : T.save}</button>} />
        <LangTabs lang={lang} setLang={(v) => window.__setAdminLang && window.__setAdminLang(v)} />
        <div style={sCard}>
          <div style={{ font: '12px/1.5 system-ui', color: C.muted, marginBottom: 14 }}>{L.hint}</div>
          <label style={lbl}>{L.updated}</label>
          <input style={{ ...sInput, marginBottom: 14 }} value={legal['updated' + sfx] || ''} onChange={(e) => setField('updated', e.target.value)} />
          <label style={lbl}>{L.intro}</label>
          <textarea style={{ ...sInput, minHeight: 90 }} value={legal['intro' + sfx] || ''} onChange={(e) => setField('intro', e.target.value)} />
        </div>
        <h3 style={{ font: '700 14px system-ui', color: C.ink, margin: '18px 0 10px' }}>{L.sectionsTitle} <span style={{ color: C.muted, fontWeight: 400 }}>· {(legal.sections || []).length}</span></h3>
        {(legal.sections || []).map((s, i) => (
          <div key={i} style={sCard}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10, gap: 8 }}>
              <span style={{ font: '700 12px system-ui', letterSpacing: 0.5, textTransform: 'uppercase', color: C.teal }}>{L.section} {i + 1}</span>
              <div style={{ display: 'flex', gap: 6 }}>
                <button style={{ ...sBtnTiny, opacity: i === 0 ? 0.4 : 1 }} disabled={i === 0} title={T.moveUp} onClick={() => moveSection(i, -1)}>↑</button>
                <button style={{ ...sBtnTiny, opacity: i === (legal.sections || []).length - 1 ? 0.4 : 1 }} disabled={i === (legal.sections || []).length - 1} title={T.moveDown} onClick={() => moveSection(i, 1)}>↓</button>
                <button style={{ ...sBtnTiny, color: C.red, borderColor: '#e7c3c0' }} onClick={() => removeSection(i)}>{T.del}</button>
              </div>
            </div>
            <label style={lbl}>{L.heading}</label>
            <input style={{ ...sInput, marginBottom: 10 }} value={s['h' + sfx] || ''} onChange={(e) => setSection(i, 'h', e.target.value)} />
            <label style={lbl}>{L.text}</label>
            <textarea style={{ ...sInput, minHeight: 110 }} value={s['body' + sfx] || ''} onChange={(e) => setSection(i, 'body', e.target.value)} />
          </div>
        ))}
        <div style={{ margin: '0 0 18px' }}>
          <button style={sBtnGhost} onClick={addSection}>{L.addSection}</button>
          <div style={{ font: '12px system-ui', color: C.muted, marginTop: 6 }}>{L.secHint}</div>
        </div>
        <div style={sCard}>
          <label style={lbl}>{L.termsTitle}</label>
          <input style={{ ...sInput, marginBottom: 10 }} value={legal['termsTitle' + sfx] || ''} onChange={(e) => setField('termsTitle', e.target.value)} />
          <label style={lbl}>{L.termsBody}</label>
          <textarea style={{ ...sInput, minHeight: 90 }} value={legal['termsBody' + sfx] || ''} onChange={(e) => setField('termsBody', e.target.value)} />
        </div>
        <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 12 }}>
          <button style={sBtn} onClick={onSave}>{saved ? T.saved : T.save}</button>
        </div>
      </div>
    );
  }
  function BrandingSection({ content, setContent, persist, lang, T }) {
    const logo = content.LOGO || { src: '', alt: '' };
    const setLogo = (k, v) => setContent({ ...content, LOGO: { ...logo, [k]: v } });
    const [saved, setSaved] = useState(false);
    const onSave = () => { persist(); setSaved(true); setTimeout(() => setSaved(false), 1800); };
    return (
      <div>
        <PageHead title={T.meta.branding[0]} sub={T.meta.branding[1]} action={<button style={sBtn} onClick={onSave}>{saved ? T.saved : T.save}</button>} />
        <div style={sCard}>
          <h3 style={{ font: '700 15px system-ui', color: C.ink, margin: '0 0 4px' }}>{T.brandLogo}</h3>
          <p style={{ font: '12.5px/1.5 system-ui', color: C.muted, margin: '0 0 4px' }}>{T.brandLogoHint}</p>
          <ImageField label={T.logoFile} value={logo.src} onChange={v => setLogo('src', v)} />
          <div><label style={sLabel}>{T.altText}</label><input style={sInput} value={logo.alt || ''} onChange={e => setLogo('alt', e.target.value)} /></div>
        </div>
        <div style={sCard}>
          <h3 style={{ font: '700 15px system-ui', color: C.ink, margin: '0 0 4px' }}>{T.brandFav}</h3>
          <p style={{ font: '12.5px/1.5 system-ui', color: C.muted, margin: '0 0 4px' }}>{T.brandFavHint}</p>
          <ImageField label={T.favFile} value={content.FAVICON || ''} onChange={v => setContent({ ...content, FAVICON: v })} />
        </div>
      </div>
    );
  }
  function Dashboard({ content, setTab, lang, T }) {
    const stats = [
      { k: 'services', col: '#006D77', icon: '◆' },
      { k: 'sectors', col: '#0e8b95', icon: '◇' },
      { k: 'news', col: '#1f5f53', icon: '◐' },
      { k: 'partners', col: '#5b4a63', icon: '◑' },
    ];
    const keyMap = { services: 'SERVICES', sectors: 'SECTORS', news: 'NEWS', partners: 'PARTNERS' };
    const news = (content.NEWS || []).slice().sort((a, b) => (b.date || '').localeCompare(a.date || '')).slice(0, 5);
    let subs = []; try { subs = JSON.parse(localStorage.getItem('bilermen_submissions') || '[]'); } catch (e) {}
    const newSubs = subs.filter(s => (s.status || 'new') === 'new').length;
    const D = lang === 'ru'
      ? { quick: 'Быстрые действия', qNews: '+ Новая статья', qService: '+ Услуга', qPartner: '+ Партнёр', qSubs: 'Заявки', subsCard: 'Заявки', subsNew: 'новых', tip: 'Подсказка: после правок нажмите «Опубликовать», чтобы изменения увидели все посетители.' }
      : { quick: 'Quick actions', qNews: '+ New article', qService: '+ Service', qPartner: '+ Partner', qSubs: 'Submissions', subsCard: 'Submissions', subsNew: 'new', tip: 'Tip: after editing, click “Publish” so every visitor sees the changes.' };
    return (
      <div>
        <PageHead title={T.meta.dashboard[0]} sub={T.meta.dashboard[1]} />
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 14, marginBottom: 14 }}>
          {stats.map(({ k, col, icon }) => (
            <div key={k} onClick={() => setTab(k)} style={{ ...sCard, marginBottom: 0, cursor: 'pointer', position: 'relative', overflow: 'hidden', borderTop: '3px solid ' + col }}>
              <div style={{ position: 'absolute', top: 8, right: 12, font: '30px system-ui', color: col, opacity: 0.16 }}>{icon}</div>
              <div style={{ font: '800 38px/1 system-ui', color: col }}>{(content[keyMap[k]] || []).length}</div>
              <div style={{ font: '600 11px system-ui', letterSpacing: 1.1, textTransform: 'uppercase', color: C.muted, marginTop: 8 }}>{T.counts[k]}</div>
            </div>
          ))}
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr', gap: 14, marginBottom: 14 }}>
          <div style={{ ...sCard, marginBottom: 0 }}>
            <h3 style={{ font: '700 12px system-ui', letterSpacing: 0.6, textTransform: 'uppercase', color: C.muted, margin: '0 0 12px' }}>{D.quick}</h3>
            <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
              <button style={sBtn} onClick={() => setTab('news')}>{D.qNews}</button>
              <button style={sBtnGhost} onClick={() => setTab('services')}>{D.qService}</button>
              <button style={sBtnGhost} onClick={() => setTab('partners')}>{D.qPartner}</button>
              <button style={sBtnGhost} onClick={() => setTab('submissions')}>{D.qSubs}</button>
            </div>
            <div style={{ font: '12px/1.6 system-ui', color: C.muted, marginTop: 16, paddingTop: 14, borderTop: '1px solid ' + C.line }}>{D.tip}</div>
          </div>
          <div onClick={() => setTab('submissions')} style={{ ...sCard, marginBottom: 0, cursor: 'pointer', background: 'linear-gradient(135deg,#06343a,#0a1f26)', color: '#fff' }}>
            <div style={{ font: '600 11px system-ui', letterSpacing: 1, textTransform: 'uppercase', opacity: 0.7 }}>{D.subsCard}</div>
            <div style={{ font: '800 36px/1 system-ui', marginTop: 10 }}>{subs.length}</div>
            <div style={{ font: '12px system-ui', marginTop: 6, color: '#7fd1d8' }}>{newSubs} {D.subsNew}</div>
          </div>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
          <div style={{ ...sCard, marginBottom: 0 }}>
            <h3 style={{ font: '700 16px system-ui', color: C.ink, margin: '0 0 12px' }}>{T.latestNews}</h3>
            {news.map((n, i) => (
              <div key={i} style={{ padding: '10px 0', borderBottom: i < news.length - 1 ? '1px solid ' + C.line : 'none', cursor: 'pointer' }} onClick={() => setTab('news')}>
                <div style={{ font: '600 14px system-ui', color: C.ink }}>{n['title_' + lang] || n.title || '-'}</div>
                <div style={{ font: '12px system-ui', color: C.muted, marginTop: 3 }}>{(n['category_' + lang] || n.category || '')}{n.date ? ' · ' + n.date : ''}</div>
              </div>
            ))}
            {news.length === 0 && <div style={{ color: '#888', font: '13px system-ui' }}>{T.noNews}</div>}
          </div>
          <div style={{ ...sCard, marginBottom: 0 }}>
            <h3 style={{ font: '700 16px system-ui', color: C.ink, margin: '0 0 12px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>{D.subsCard}<span style={{ font: '600 12px system-ui', color: C.teal, cursor: 'pointer' }} onClick={() => setTab('submissions')}>{lang === 'ru' ? 'Все' : 'All'} &rarr;</span></h3>
            {subs.slice(0, 5).map((sx, i) => (
              <div key={i} onClick={() => setTab('submissions')} style={{ padding: '10px 0', borderBottom: i < Math.min(subs.length, 5) - 1 ? '1px solid ' + C.line : 'none', cursor: 'pointer', display: 'flex', justifyContent: 'space-between', gap: 10, alignItems: 'flex-start' }}>
                <div style={{ minWidth: 0 }}>
                  <div style={{ font: '600 14px system-ui', color: C.ink, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{(sx.name || '-') + (sx.company ? ' · ' + sx.company : '')}</div>
                  <div style={{ font: '12px system-ui', color: C.muted, marginTop: 3, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{(sx.interest || sx.email || '') + (sx.date ? ' · ' + sx.date : '')}</div>
                </div>
                <span style={{ flex: '0 0 auto', font: '600 10px system-ui', padding: '3px 8px', borderRadius: 20, background: sx.status === 'closed' ? '#e7eceb' : sx.status === 'contacted' ? '#cdeef0' : '#d8f3dc', color: C.ink }}>{sx.status || 'new'}</span>
              </div>
            ))}
            {subs.length === 0 && <div style={{ color: '#888', font: '13px system-ui' }}>{lang === 'ru' ? 'Заявок пока нет.' : 'No submissions yet.'}</div>}
          </div>
        </div>
      </div>
    );
  }
  function Submissions({ T, lang }) {
    const SKEY = 'bilermen_submissions';
    const blank = { date: '', name: '', company: '', email: '', phone: '', interest: '', message: '', status: 'new' };
    const SAMPLES = [
      { date: '2026-05-28', name: 'Aydyn Myradow', company: 'CaspianTrade LLC', email: 'a.myradow@example.com', phone: '+993 65 123456', interest: 'Market entry / Energy', message: 'Looking to enter the Turkmen market; need a local partner.', status: 'new' },
      { date: '2026-05-22', name: 'Laura Fischer', company: 'Helvetica AG', email: 'l.fischer@example.com', phone: '+41 44 1234567', interest: 'Distributor search', message: 'Need a local distributor for industrial equipment.', status: 'contacted' },
      { date: '2026-05-15', name: 'James Okoro', company: 'Sahel Energy', email: 'j.okoro@example.com', phone: '+234 80 9988776', interest: 'Representation & Operations', message: 'Exploring a local representative office in Ashgabat.', status: 'closed' },
    ];
    const load = () => { const r = localStorage.getItem(SKEY); if (r != null) { try { return JSON.parse(r); } catch (e) {} } return SAMPLES.slice(); };
    const [rows, setRows] = useState(load);
    const [editing, setEditing] = useState(null);
    const save = (next) => { setRows(next); try { localStorage.setItem(SKEY, JSON.stringify(next)); } catch (e) {} };
    const cols = ['date', 'name', 'company', 'email', 'phone', 'interest', 'message', 'status'];
    const L = lang === 'ru'
      ? { add: '+ Добавить заявку', edit: 'Изменить', del: 'Удалить', exp: 'Экспорт в Excel', empty: 'Заявок пока нет. Добавьте вручную, либо подключим автосбор на этапе Supabase.', save: 'Сохранить', cancel: 'Отмена', confirmDel: 'Удалить эту заявку?', sNew: 'Новая', sCont: 'Связались', sClosed: 'Закрыта', c: { date: 'Дата', name: 'Имя', company: 'Компания', email: 'Email', phone: 'Телефон', interest: 'Интерес', message: 'Сообщение', status: 'Статус' } }
      : { add: '+ Add submission', edit: 'Edit', del: 'Delete', exp: 'Export to Excel', empty: 'No submissions yet. Add them manually, or we will enable auto-capture at the Supabase step.', save: 'Save', cancel: 'Cancel', confirmDel: 'Delete this submission?', sNew: 'New', sCont: 'Contacted', sClosed: 'Closed', c: { date: 'Date', name: 'Name', company: 'Company', email: 'Email', phone: 'Phone', interest: 'Interest', message: 'Message', status: 'Status' } };
    const esc = (s) => String(s == null ? '' : s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
    const exportXls = () => {
      const th = cols.map(k => '<th style="background:#0A1F26;color:#fff;padding:9px 13px;text-align:left;font-family:Arial;font-size:12px;border:1px solid #0A1F26;">' + esc(L.c[k]) + '</th>').join('');
      const trs = rows.map((r, idx) => '<tr style="background:' + (idx % 2 ? '#eef4f4' : '#ffffff') + ';">' + cols.map(k => '<td style="padding:8px 13px;border:1px solid #cfdada;font-family:Arial;font-size:13px;color:#0A1F26;">' + esc(r[k]) + '</td>').join('') + '</tr>').join('');
      const html = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel"><head><meta charset="utf-8"></head><body><table style="border-collapse:collapse">' + '<thead><tr>' + th + '</tr></thead><tbody>' + trs + '</tbody></table></body></html>';
      const blob = new Blob(['﻿', html], { type: 'application/vnd.ms-excel' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a'); a.href = url; a.download = 'bilermen-submissions.xls';
      document.body.appendChild(a); a.click(); a.remove(); setTimeout(() => URL.revokeObjectURL(url), 1500);
    };
    const stLabel = (s) => s === 'closed' ? L.sClosed : s === 'contacted' ? L.sCont : L.sNew;
    if (editing) {
      const d = editing.draft;
      const ch = (k, v) => setEditing(e => ({ ...e, draft: { ...e.draft, [k]: v } }));
      const doSave = () => { const n = rows.slice(); if (editing.index === -1) n.unshift(d); else n[editing.index] = d; save(n); setEditing(null); };
      const fld = (k, type) => (
        <div>
          <label style={sLabel}>{L.c[k]}</label>
          {type === 'area'
            ? <textarea style={{ ...sInput, minHeight: 84, resize: 'vertical' }} value={d[k] || ''} onChange={e => ch(k, e.target.value)} />
            : type === 'status'
              ? <select style={sInput} value={d[k] || 'new'} onChange={e => ch(k, e.target.value)}><option value="new">{L.sNew}</option><option value="contacted">{L.sCont}</option><option value="closed">{L.sClosed}</option></select>
              : <input style={sInput} type={k === 'date' ? 'date' : 'text'} value={d[k] || ''} onChange={e => ch(k, e.target.value)} />}
        </div>
      );
      return (
        <div>
          <PageHead title={editing.index === -1 ? L.add : L.edit}
            action={<><button style={sBtnGhost} onClick={() => setEditing(null)}>{L.cancel}</button><button style={sBtn} onClick={doSave}>{L.save}</button></>} />
          <div style={sCard}>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
              {fld('date')}{fld('status', 'status')}{fld('name')}{fld('company')}{fld('email')}{fld('phone')}
            </div>
            {fld('interest')}
            {fld('message', 'area')}
          </div>
        </div>
      );
    }
    return (
      <div>
        <PageHead title={T.meta.submissions[0]} sub={T.meta.submissions[1]}
          action={<><button style={sBtnGhost} onClick={exportXls}>{L.exp}</button><button style={sBtn} onClick={() => setEditing({ index: -1, draft: { ...blank } })}>{L.add}</button></>} />
        <div style={sCard}><p style={{ font: '13px/1.7 system-ui', color: C.muted, margin: 0 }}>{T.subsBody}</p></div>
        {rows.length === 0
          ? <div style={{ color: '#888', font: '14px system-ui', marginTop: 10 }}>{L.empty}</div>
          : <div style={{ overflowX: 'auto', border: '1px solid ' + C.line, borderRadius: 10, background: '#fff' }}>
              <table style={{ borderCollapse: 'collapse', width: '100%', minWidth: 820 }}>
                <thead><tr>{['date', 'name', 'company', 'email', 'phone', 'interest', 'status'].map(k => <th key={k} style={{ background: C.sidebar, color: '#fff', font: '600 11px system-ui', letterSpacing: 0.4, textTransform: 'uppercase', textAlign: 'left', padding: '10px 12px', whiteSpace: 'nowrap' }}>{L.c[k]}</th>)}<th style={{ background: C.sidebar }}></th></tr></thead>
                <tbody>{rows.map((r, i) => (
                  <tr key={i} style={{ background: i % 2 ? '#f7fafa' : '#fff', borderTop: '1px solid ' + C.line }}>
                    {['date', 'name', 'company', 'email', 'phone', 'interest'].map(k => <td key={k} style={{ padding: '9px 12px', font: '13px system-ui', color: C.ink, whiteSpace: 'nowrap', maxWidth: 190, overflow: 'hidden', textOverflow: 'ellipsis' }}>{r[k] || '-'}</td>)}
                    <td style={{ padding: '9px 12px' }}><span style={{ font: '600 11px system-ui', padding: '3px 10px', borderRadius: 20, background: r.status === 'closed' ? '#e7eceb' : r.status === 'contacted' ? '#cdeef0' : '#d8f3dc', color: C.ink, whiteSpace: 'nowrap' }}>{stLabel(r.status)}</span></td>
                    <td style={{ padding: '9px 12px', whiteSpace: 'nowrap' }}>
                      <button style={sBtnTiny} onClick={() => setEditing({ index: i, draft: { ...r } })}>{L.edit}</button>{' '}
                      <button style={{ ...sBtnTiny, color: C.red, borderColor: '#e7c3c0' }} onClick={() => { if (confirm(L.confirmDel)) { const n = rows.slice(); n.splice(i, 1); save(n); } }}>{L.del}</button>
                    </td>
                  </tr>
                ))}</tbody>
              </table>
            </div>}
      </div>
    );
  }

  /* ----------------------------------------------------------- the app */
  function AdminScreen() {
    const [unlocked, setUnlocked] = useState(sessionStorage.getItem('bilermen_admin_ok') === '1');
    const [pass, setPass] = useState('');
    const [content, setContent] = useState(() => clone(window.SITE_DATA));
    const [tab, setTab] = useState('dashboard');
    const [lang, setLang] = useState('en');
    const [toast, setToast] = useState('');
    window.__setAdminLang = setLang;
    const [narrow, setNarrow] = useState(typeof window !== 'undefined' && window.innerWidth <= 1024);
    React.useEffect(() => {
      const onResize = () => setNarrow(window.innerWidth <= 1024);
      window.addEventListener('resize', onResize);
      return () => window.removeEventListener('resize', onResize);
    }, []);

    const flash = (m) => { setToast(m); setTimeout(() => setToast(''), 2600); };
    const persistObj = (obj) => { try { localStorage.setItem(DRAFT_KEY, JSON.stringify(obj)); return true; } catch (e) { flash(lang === 'ru' ? 'Не удалось сохранить (большие фото?).' : 'Could not save (large images?).'); return false; } };
    const persist = () => persistObj(content);
    const commit = (next) => { setContent(next); persistObj(next); }; // structural change + save
    const publish = () => {
      const json = JSON.stringify(content, null, 2);
      const text = '/* Bilermen - site content. Exported from the admin panel.\n   Replace data.js in your deploy with this file and re-publish. */\n\n' +
        'window.SITE_DATA = ' + json + ';\n\n' +
        '(function applyAdminDraft(){try{var raw=localStorage.getItem("' + DRAFT_KEY + '");if(!raw)return;var d=JSON.parse(raw);if(d&&Array.isArray(d.SERVICES)&&Array.isArray(d.SECTORS)){window.SITE_DATA=d;window.__BILERMEN_DRAFT__=true;}}catch(e){}})();\n';
      const blob = new Blob([text], { type: 'text/javascript' });
      const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'data.js'; a.click(); URL.revokeObjectURL(a.href);
      persistObj(content); flash(STR[lang].published);
    };
    const T = STR[lang];

    if (!unlocked) {
      const tryLogin = () => { if (pass === PASS) { sessionStorage.setItem('bilermen_admin_ok', '1'); setUnlocked(true); } else flash(T.wrongPass); };
      return (
        <div style={{ minHeight: '100vh', background: C.sidebar, display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: 'system-ui, sans-serif' }}>
          <div style={{ width: 350, background: '#fff', borderRadius: 14, padding: 34, textAlign: 'center' }}>
            <img src="assets/bilermen-lockup.svg" alt="Bilermen Hyzmatdashlar" style={{ height: 40, display: 'block', margin: '0 auto 16px' }} />
            <h1 style={{ font: '700 20px system-ui', color: C.ink, margin: '0 0 4px' }}>{T.login}</h1>
            <p style={{ color: '#666', fontSize: 13, marginTop: 0, marginBottom: 18 }}>{T.loginSub}</p>
            <input style={{ ...sInput, marginBottom: 10 }} type="password" placeholder={T.password} value={pass} onChange={e => setPass(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') tryLogin(); }} autoFocus />
            <button style={{ ...sBtn, width: '100%' }} onClick={tryLogin}>{T.signin}</button>
            <div style={{ marginTop: 14, display: 'inline-flex', background: C.soft, borderRadius: 8, padding: 3 }}>
              {[['en', 'EN'], ['ru', 'RU']].map(([v, l]) => <button key={v} onClick={() => setLang(v)} style={{ padding: '5px 12px', border: 0, borderRadius: 6, cursor: 'pointer', font: '600 12px system-ui', background: lang === v ? C.teal : 'transparent', color: lang === v ? '#fff' : C.ink }}>{l}</button>)}
            </div>
            {toast && <div style={{ marginTop: 12, color: C.red, fontSize: 13 }}>{toast}</div>}
          </div>
        </div>
      );
    }

    const NAV = ['dashboard', 'hero', 'services', 'sectors', 'advantages', 'news', 'partners', 'contact', 'branding', 'legal', 'submissions'];
    const ICON = { dashboard: '⌂', hero: '⊕', services: '◆', sectors: '◇', advantages: '★', news: '◐', partners: '◑', contact: '✉', branding: '✦', legal: '§', submissions: '☰' };
    const openSite = () => { window.location.assign(window.location.pathname + '#/'); window.location.reload(); };

    let body;
    if (tab === 'dashboard') body = <Dashboard content={content} setTab={setTab} lang={lang} T={T} />;
    else if (tab === 'hero') body = <HeroIntroSection content={content} setContent={setContent} persist={persist} lang={lang} T={T} />;
    else if (tab === 'contact') body = <ContactSection content={content} setContent={setContent} persist={persist} lang={lang} T={T} />;
    else if (tab === 'branding') body = <BrandingSection content={content} setContent={setContent} persist={persist} lang={lang} T={T} />;
    else if (tab === 'legal') body = <LegalSection content={content} setContent={setContent} commit={commit} persist={persist} lang={lang} T={T} />;
    else if (tab === 'submissions') body = <Submissions T={T} lang={lang} />;
    else body = <ListSection secKey={tab} content={content} commit={commit} lang={lang} T={T} />;

    return (
      <div style={{ display: 'flex', flexDirection: narrow ? 'column' : 'row', minHeight: '100vh', fontFamily: 'system-ui, sans-serif', background: C.soft }}>
        <aside style={{ flex: narrow ? '0 0 auto' : '0 0 234px', width: narrow ? '100%' : 'auto', background: C.sidebar, color: '#cdd8d8', display: 'flex', flexDirection: 'column', position: narrow ? 'static' : 'sticky', top: 0, height: narrow ? 'auto' : '100vh' }}>
          <div style={{ padding: '22px 22px 18px', borderBottom: '1px solid rgba(255,255,255,0.08)' }}>
            <div style={{ display: 'flex', gap: 3, marginBottom: 10 }}>
              <span style={{ width: 5, height: 22, background: '#1f6f86', transform: 'skewX(-12deg)' }} />
              <span style={{ width: 5, height: 22, background: '#2f8f99', transform: 'skewX(-12deg)' }} />
              <span style={{ width: 5, height: 22, background: '#5fb3bb', transform: 'skewX(-12deg)' }} />
              <span style={{ width: 5, height: 22, background: '#9fd6da', transform: 'skewX(-12deg)' }} />
            </div>
            <div style={{ font: '700 13px system-ui', color: '#fff', letterSpacing: 0.5 }}>BILERMEN</div>
            <div style={{ font: '600 10px system-ui', color: '#7f9799', letterSpacing: 1.5, textTransform: 'uppercase', marginTop: 2 }}>{T.panel}</div>
          </div>
          <nav style={{ padding: '12px', flex: 1, overflowY: narrow ? 'hidden' : 'auto', display: narrow ? 'flex' : 'block', overflowX: narrow ? 'auto' : 'visible', gap: narrow ? 6 : 0 }}>
            {NAV.map(k => (
              <div key={k} onClick={() => setTab(k)} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '10px 12px', borderRadius: 8, cursor: 'pointer', marginBottom: narrow ? 0 : 2, whiteSpace: 'nowrap', flex: narrow ? '0 0 auto' : 'none', font: '600 14px system-ui', color: tab === k ? '#fff' : '#aebcbc', background: tab === k ? C.teal : 'transparent' }}>
                <span style={{ width: 16, textAlign: 'center', opacity: 0.9 }}>{ICON[k]}</span>{T.nav[k]}
              </div>
            ))}
          </nav>
          <div style={{ padding: '14px 16px', borderTop: '1px solid rgba(255,255,255,0.08)' }}>
            <button onClick={publish} style={{ ...sBtn, width: '100%', marginBottom: 8 }}>{T.publish}</button>
            <div onClick={openSite} style={{ font: '600 13px system-ui', color: '#7fc6cd', cursor: 'pointer', textAlign: 'center' }}>{T.openSite}</div>
          </div>
        </aside>

        <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column' }}>
          <div style={{ background: '#fffbe6', borderBottom: '1px solid #f0e6b0', padding: '9px 26px', font: '12.5px/1.5 system-ui', color: '#6a5a17', display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap' }}>
            <span style={{ flex: 1, minWidth: 200 }}>{T.publishHint}</span>
            <div style={{ display: 'inline-flex', background: '#fff', border: '1px solid #e7dca0', borderRadius: 8, padding: 2 }}>
              {[['en', 'EN'], ['ru', 'RU']].map(([v, l]) => <button key={v} onClick={() => setLang(v)} style={{ padding: '5px 12px', border: 0, borderRadius: 6, cursor: 'pointer', font: '600 12px system-ui', background: lang === v ? C.teal : 'transparent', color: lang === v ? '#fff' : C.ink }}>{l}</button>)}
            </div>
          </div>
          <div style={{ padding: '26px 26px 90px', maxWidth: 960 }}>{body}</div>
        </div>

        {toast && <div style={{ position: 'fixed', bottom: 20, left: '50%', transform: 'translateX(-50%)', background: C.ink, color: '#fff', padding: '12px 20px', borderRadius: 10, font: '14px system-ui', zIndex: 50, boxShadow: '0 8px 24px rgba(0,0,0,0.2)' }}>{toast}</div>}
      </div>
    );
  }
  return AdminScreen;
})();

window.AdminScreen = AdminUI;
