/* flows.jsx — Report sheet, Saved places, Onboarding, Auth, Community contribution. */

// Hard login gate: when a backend is connected and there's no saved session, the user must
// authenticate before browsing. Mirrors the initial-screen gate in app.jsx. Returns false when
// the backend is off (offline/seed demo stays freely browsable) or localStorage is blocked.
function needsAuthGate() {
  try { return !!(window.VR_DB && window.VR_DB.enabled) && !localStorage.getItem('vr-auth'); }
  catch (e) { return false; }
}

function SubShell({ theme, title, onBack, children, footer, action }) {
  const { IconBack } = window;
  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 60, background: 'var(--bg)', display: 'flex', flexDirection: 'column' }}>
      <div style={{ padding: '56px 14px 8px', display: 'flex', alignItems: 'center', gap: 6, flexShrink: 0 }}>
        <button onClick={onBack} className="tap" style={{ background: 'none', border: 'none', color: 'var(--text)', cursor: 'pointer', padding: 4 }}>
          <IconBack size={26} />
        </button>
        <h1 style={{ margin: 0, flex: 1, minWidth: 0, fontSize: 24, fontWeight: 800, letterSpacing: -0.4, color: 'var(--text)' }}>{title}</h1>
        {action}
      </div>
      <div className="noscroll" style={{ flex: 1, overflowY: 'auto', padding: '6px 0 20px' }}>{children}</div>
      {footer && <div style={{ padding: '10px 16px 30px', flexShrink: 0, borderTop: '0.5px solid var(--hairline)' }}>{footer}</div>}
    </div>
  );
}

function PrimaryBtn({ children, onClick, style }) {
  return (
    <button onClick={onClick} className="tap" style={{
      width: '100%', height: 54, borderRadius: 16, border: 'none', cursor: 'pointer',
      background: 'var(--brand)', color: '#fff', fontSize: 17, fontWeight: 800,
      display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 9,
      boxShadow: '0 8px 22px color-mix(in oklch, var(--brand) 38%, transparent)', ...style,
    }}>{children}</button>
  );
}

// ============================================================
// REPORT SHEET (Докладвай) — 2-tap hazard report
// ============================================================
function ReportSheet({ theme, open, onClose }) {
  const { glassStyle, IconWarn, IconCar, IconBike, IconCrash, IconConstruction, IconBulb, IconCamera, IconCheck, IconClose } = window;
  const [sent, setSent] = React.useState(null);
  React.useEffect(() => { if (!open) setSent(null); }, [open]);
  if (!open) return null;
  const cats = [
    { label: 'Дупка', Icon: IconWarn, level: 'danger' },
    { label: 'Опасно движение', Icon: IconCar, level: 'danger' },
    { label: 'Блокирана алея', Icon: IconBike, level: 'moderate' },
    { label: 'Произшествие', Icon: IconCrash, level: 'danger' },
    { label: 'Пътен ремонт', Icon: IconConstruction, level: 'moderate' },
    { label: 'Лошо осветление', Icon: IconBulb, level: 'moderate' },
  ];
  const pick = (c) => { setSent(c); setTimeout(() => { onClose && onClose(); }, 1500); };

  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 120, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end' }}>
      <div onClick={onClose} style={{ position: 'absolute', inset: 0, background: 'rgba(10,12,16,0.45)' }} />
      <div style={{ position: 'relative', borderRadius: '26px 26px 0 0', padding: '10px 18px 30px', boxShadow: 'var(--shadow-lg)', ...glassStyle(theme, true) }}>
        <div style={{ width: 40, height: 5, borderRadius: 9, background: 'var(--hairline)', margin: '0 auto 10px' }} />
        {sent ? (
          <div style={{ padding: '18px 8px 24px', textAlign: 'center' }}>
            <div style={{ width: 68, height: 68, borderRadius: 68, margin: '0 auto 16px', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'color-mix(in oklch, var(--safe) 18%, transparent)', color: 'var(--safe)' }}>
              <IconCheck size={38} sw={2.4} />
            </div>
            <div style={{ fontSize: 21, fontWeight: 800, color: 'var(--text)' }}>Сигналът е изпратен</div>
            <div style={{ fontSize: 14.5, color: 'var(--muted)', fontWeight: 500, marginTop: 6 }}>{sent.label} · благодарим, че пазиш града по-безопасен.</div>
          </div>
        ) : (
          <>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 2 }}>
              <h2 style={{ margin: 0, fontSize: 21, fontWeight: 800, color: 'var(--text)' }}>Подайте сигнал</h2>
              <button onClick={onClose} className="tap" style={{ background: 'var(--surface-2)', border: 'none', borderRadius: 20, width: 34, height: 34, cursor: 'pointer', color: 'var(--muted)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><IconClose size={18} /></button>
            </div>
            <div style={{ fontSize: 14, color: 'var(--muted)', fontWeight: 500, marginBottom: 14 }}>Изберете тип — без писане, само едно докосване.</div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 10 }}>
              {cats.map((c) => (
                <button key={c.label} onClick={() => pick(c)} className="tap" style={{
                  background: 'var(--surface)', border: 'none', borderRadius: 16, cursor: 'pointer',
                  padding: '14px 6px 11px', boxShadow: 'var(--shadow)', color: 'var(--text)',
                  display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8,
                }}>
                  <span style={{ width: 44, height: 44, borderRadius: 13, display: 'flex', alignItems: 'center', justifyContent: 'center', background: `color-mix(in oklch, var(--${c.level}) 16%, transparent)`, color: `var(--${c.level})` }}><c.Icon size={24} /></span>
                  <span style={{ fontSize: 12, fontWeight: 600, lineHeight: 1.15, textAlign: 'center' }}>{c.label}</span>
                </button>
              ))}
            </div>
            <button className="tap" style={{ marginTop: 14, width: '100%', height: 48, borderRadius: 14, border: '1.5px dashed var(--hairline)', background: 'none', cursor: 'pointer', color: 'var(--muted)', fontSize: 15, fontWeight: 600, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8 }}>
              <IconCamera size={20} /> Добави снимка (по желание)
            </button>
          </>
        )}
      </div>
    </div>
  );
}

// ============================================================
// SHARED STORES — saved places, route prefs, community posts
// (module-level so multiple screens stay in sync)
// ============================================================
function makeStore(initial, persistKey) {
  let state = initial;
  if (persistKey) {
    try { const raw = localStorage.getItem(persistKey); if (raw) state = JSON.parse(raw); } catch (e) { /* ignore */ }
  }
  const subs = new Set();
  const emit = () => {
    if (persistKey) { try { localStorage.setItem(persistKey, JSON.stringify(state)); } catch (e) { /* ignore */ } }
    subs.forEach((f) => f());
  };
  return {
    get: () => state,
    subscribe: (f) => { subs.add(f); return () => subs.delete(f); },
    set: (next) => { state = typeof next === 'function' ? next(state) : next; emit(); },
  };
}
function useStore(store) {
  return React.useSyncExternalStore(store.subscribe, store.get);
}

const SavedStore = makeStore([
  { id: 'home', Icon: 'IconHome', label: 'Вкъщи', addr: 'ж.к. Лозенец' },
  { id: 'work', Icon: 'IconBriefcase', label: 'Работа', addr: 'бул. Цариградско шосе 47' },
  { id: 'uni', Icon: 'IconStar', label: 'Университет', addr: 'СУ · бул. Цар Освободител 15' },
  { id: 'gym', Icon: 'IconStar', label: 'Фитнес', addr: 'бул. Витоша 102' },
], 'vr_saved');
// fire-and-forget write-through to Supabase (only when signed in); local store is the source of truth
function vrFavPush(method, kind, arg) {
  const DB = window.VR_DB;
  if (!DB || !DB.enabled) return;
  DB.currentUser().then((u) => { if (u && DB[method]) DB[method](kind, arg); });
}
const Saved = {
  add: (p) => { const id = p.id || ('p' + Date.now()); const obj = { ...p, id }; SavedStore.set((l) => l.some((x) => x.id === id) ? l : [...l, obj]); vrFavPush('saveFavorite', 'place', obj); },
  remove: (id) => { SavedStore.set((l) => l.filter((x) => x.id !== id)); vrFavPush('removeFavorite', 'place', id); },
  has: (id) => SavedStore.get().some((x) => x.id === id),
  toggle: (p) => { const on = SavedStore.get().some((x) => x.id === p.id); SavedStore.set((l) => on ? l.filter((x) => x.id !== p.id) : [...l, p]); on ? vrFavPush('removeFavorite', 'place', p.id) : vrFavPush('saveFavorite', 'place', p); },
};
function useSaved() { return useStore(SavedStore); }

// ── favorite ROUTES (persisted) — saved from the route-select screen, shown in Routes ▸ Saved ──
const vrSlug = (s) => 'r_' + String(s || '').toLowerCase().replace(/[^a-z0-9а-я]+/gi, '_').slice(0, 40);
const SavedRoutesStore = makeStore([], 'vr_saved_routes');
const SavedRoutes = {
  routeId: (from, to) => vrSlug(from + '__' + to),
  add: (r) => { SavedRoutesStore.set((l) => l.some((x) => x.id === r.id) ? l : [r, ...l]); vrFavPush('saveFavorite', 'route', r); },
  remove: (id) => { SavedRoutesStore.set((l) => l.filter((x) => x.id !== id)); vrFavPush('removeFavorite', 'route', id); },
  has: (id) => SavedRoutesStore.get().some((x) => x.id === id),
  toggle: (r) => { const on = SavedRoutesStore.get().some((x) => x.id === r.id); SavedRoutesStore.set((l) => on ? l.filter((x) => x.id !== r.id) : [r, ...l]); on ? vrFavPush('removeFavorite', 'route', r.id) : vrFavPush('saveFavorite', 'route', r); },
};
function useSavedRoutes() { return useStore(SavedRoutesStore); }

// pull remote favorites on login and union them into the local stores (remote wins on id match).
// Called from app.jsx after a user signs in. Safe to call when offline (no-op).
window.vrSyncFavorites = async function () {
  const DB = window.VR_DB;
  if (!DB || !DB.enabled) return;
  const u = await DB.currentUser();
  if (!u) return;
  const rows = await DB.fetchFavorites();
  if (!rows || !rows.length) return;
  const merge = (store, kind) => {
    const remote = rows.filter((r) => r.kind === kind && r.payload && r.payload.id).map((r) => r.payload);
    if (!remote.length) return;
    store.set((l) => {
      const byId = new Map(l.map((x) => [x.id, x]));
      remote.forEach((p) => byId.set(p.id, p)); // remote wins
      return Array.from(byId.values());
    });
  };
  merge(SavedStore, 'place');
  merge(SavedRoutesStore, 'route');
};

// ── recent destinations + completed trips (persisted) — populated from real user activity ──
const RecentStore = makeStore([], 'vr_recents');
const Recents = {
  add: (p) => {
    if (!p || !p.name) return;
    RecentStore.set((l) => [{ ...p }, ...l.filter((x) => x.name !== p.name)].slice(0, 8));
  },
};
function useRecents() { return useStore(RecentStore); }

const TripsStore = makeStore([], 'vr_trips');
const Trips = {
  add: (t) => { if (!t) return; const id = t.id || ('t' + Date.now()); TripsStore.set((l) => [{ ...t, id }, ...l].slice(0, 20)); },
};
function useTrips() { return useStore(TripsStore); }

// relative "Днес · 08:24" / "Вчера · 18:10" / "3 юни · 09:02" label for the trips list
function vrWhen(ts) {
  if (!ts) return '';
  const d = new Date(ts), now = new Date();
  const hhmm = `${d.getHours()}:${String(d.getMinutes()).padStart(2, '0')}`;
  const dayDiff = Math.floor((new Date(now.getFullYear(), now.getMonth(), now.getDate()) - new Date(d.getFullYear(), d.getMonth(), d.getDate())) / 864e5);
  if (dayDiff <= 0) return `Днес · ${hhmm}`;
  if (dayDiff === 1) return `Вчера · ${hhmm}`;
  const MON = ['яну', 'фев', 'март', 'апр', 'май', 'юни', 'юли', 'авг', 'сеп', 'окт', 'ное', 'дек'];
  return `${d.getDate()} ${MON[d.getMonth()]} · ${hhmm}`;
}

const STYLE_LABEL = { safe: 'Най-безопасен', balanced: 'Балансиран', fast: 'Най-бърз' };
const PrefsStore = makeStore({ style: 'safe', lanes: true, hills: false, traffic: true, lights: false });
function usePrefs() { return useStore(PrefsStore); }

// voice-guidance preference (persisted) — read by Profile + the active-nav screen / engine
const VoicePref = makeStore(true, 'vr_voice');
function useVoicePref() { return useStore(VoicePref); }

const COMM_OFFICIAL_AT = 20; // votes needed to become an official, map-wide hazard
const CommStore = makeStore([
  { id: 'c1', cat: 'Дупка', Icon: 'IconWarn', level: 'moderate', loc: 'ул. Граф Игнатиев', ago: 'преди 12 мин', author: 'Петър К.', votes: 8, voted: false, onMap: false },
]);
const Comm = {
  vote: (id) => {
    const item = CommStore.get().find((r) => r.id === id);
    CommStore.set((l) => l.map((r) => r.id === id ? { ...r, voted: !r.voted, votes: r.votes + (r.voted ? -1 : 1) } : r));
    // live feed item + signed in → persist the confirmation/dispute to Supabase
    if (item && item.live && item.reportId && window.VR_DB && window.VR_DB.enabled) {
      window.VR_DB.currentUser().then((u) => {
        if (!u) return;
        window.VR_DB.confirmReport(item.reportId, item.voted ? -1 : 1)
          .then((res) => { if (res && !res.error && window.vrHydrateCommunity) window.vrHydrateCommunity(); });
      });
    }
  },
  toggleMap: (id) => CommStore.set((l) => l.map((r) => r.id === id ? { ...r, onMap: !r.onMap } : r)),
};
const isOfficial = (r) => r.votes >= COMM_OFFICIAL_AT;
function useComm() { return useStore(CommStore); }

// ── current signed-in user (set from app.jsx; read by Profile, the search avatar, etc.) ──
const UserStore = makeStore(null);
function useUser() { return useStore(UserStore); }
function vrDisplayName(user) {
  if (!user) return null;
  return (user.user_metadata && user.user_metadata.name)
    || (user.email ? user.email.split('@')[0] : 'Колоездач');
}
function vrInitials(name) {
  if (!name) return '';
  const parts = name.trim().split(/\s+/).filter(Boolean);
  if (parts.length >= 2) return (parts[0][0] + parts[1][0]).toUpperCase();
  return name.trim().slice(0, 2).toUpperCase();
}

function SubLabel({ children, style }) {
  return <div style={{ padding: '16px 6px 8px', fontSize: 12.5, fontWeight: 700, letterSpacing: 0.4, textTransform: 'uppercase', color: 'var(--faint)', ...style }}>{children}</div>;
}

// ============================================================
// ЗАПАЗЕНИ МЕСТА (Saved places) — add / remove / edit
// ============================================================
function SavedPlacesScreen({ theme, go }) {
  const { IconChevR, IconPlus, IconStar } = window;
  const places = useSaved();
  const [edit, setEdit] = React.useState(false);
  const [adding, setAdding] = React.useState(false);
  React.useEffect(() => { if (places.length === 0 && edit) setEdit(false); }, [places.length, edit]);

  return (
    <SubShell theme={theme} title="Запазени места" onBack={() => go('profile')}
      action={places.length > 0 && (
        <button onClick={() => setEdit((e) => !e)} className="tap" style={{
          background: edit ? 'var(--brand)' : 'var(--surface)', border: 'none', borderRadius: 16, height: 34, padding: '0 15px',
          cursor: 'pointer', fontSize: 14.5, fontWeight: 700, color: edit ? '#fff' : 'var(--brand)', boxShadow: edit ? 'none' : 'var(--shadow)',
        }}>{edit ? 'Готово' : 'Промени'}</button>
      )}
      footer={<PrimaryBtn onClick={() => setAdding(true)}><IconPlus size={20} /> Добави място</PrimaryBtn>}>

      {places.length === 0 ? (
        <div style={{ margin: '40px 24px', textAlign: 'center' }}>
          <div style={{ width: 64, height: 64, borderRadius: 64, margin: '0 auto 16px', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'color-mix(in oklch, var(--brand) 12%, transparent)', color: 'var(--brand)' }}><IconStar size={30} /></div>
          <div style={{ fontSize: 18, fontWeight: 800 }}>Още няма запазени места</div>
          <div style={{ fontSize: 14.5, color: 'var(--muted)', fontWeight: 500, marginTop: 8, lineHeight: 1.45 }}>Добави вкъщи, работа или любими дестинации за по-бързо планиране.</div>
        </div>
      ) : (
        <div style={{ background: 'var(--surface)', borderRadius: 18, margin: '6px 16px', boxShadow: 'var(--shadow)', overflow: 'hidden' }}>
          {places.map((p, i) => {
            const Ico = window[p.Icon] || window.IconPin;
            return (
              <div key={p.id} onClick={edit ? undefined : () => go('route')} className={edit ? '' : 'tap'} style={{ display: 'flex', alignItems: 'center', gap: 13, padding: '14px 15px', cursor: edit ? 'default' : 'pointer', borderTop: i ? '0.5px solid var(--hairline)' : 'none' }}>
                {edit && (
                  <button onClick={(e) => { e.stopPropagation(); Saved.remove(p.id); }} className="tap" aria-label="Премахни" style={{ width: 24, height: 24, borderRadius: 24, flexShrink: 0, border: 'none', cursor: 'pointer', background: 'var(--danger)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                    <span style={{ width: 11, height: 2.4, borderRadius: 2, background: '#fff' }} />
                  </button>
                )}
                <span style={{ width: 40, height: 40, borderRadius: 12, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'color-mix(in oklch, var(--brand) 13%, transparent)', color: 'var(--brand)' }}><Ico size={21} /></span>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 16, fontWeight: 700 }}>{p.label}</div>
                  <div style={{ fontSize: 13, color: 'var(--muted)', fontWeight: 500, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{p.addr}</div>
                </div>
                {!edit && <IconChevR size={18} style={{ color: 'var(--faint)' }} />}
              </div>
            );
          })}
        </div>
      )}
      <div style={{ fontSize: 13, color: 'var(--faint)', fontWeight: 500, padding: '12px 22px' }}>Запазените места се появяват най-отгоре при търсене за по-бързо планиране. Можеш да ги добавяш и от резултатите при търсене.</div>

      {adding && <AddPlaceSheet theme={theme} onClose={() => setAdding(false)} onAdd={(p) => { Saved.add(p); setAdding(false); }} />}
    </SubShell>
  );
}

function AddPlaceSheet({ theme, onClose, onAdd }) {
  const { glassStyle, IconClose, IconHome, IconBriefcase, IconStar, IconPin, IconCheck } = window;
  const [label, setLabel] = React.useState('');
  const [addr, setAddr] = React.useState('');
  const [icon, setIcon] = React.useState('IconStar');
  const ICONS = [['IconHome', IconHome], ['IconBriefcase', IconBriefcase], ['IconStar', IconStar], ['IconPin', IconPin]];
  const valid = label.trim().length > 0;
  const field = { width: '100%', height: 50, padding: '0 14px', borderRadius: 13, marginBottom: 11, border: '1px solid var(--hairline)', background: 'var(--surface-2)', outline: 'none', fontSize: 16, fontFamily: 'inherit', color: 'var(--text)' };
  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 120, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end' }}>
      <div onClick={onClose} style={{ position: 'absolute', inset: 0, background: 'rgba(10,12,16,0.45)' }} />
      <div style={{ position: 'relative', borderRadius: '26px 26px 0 0', padding: '10px 18px 28px', boxShadow: 'var(--shadow-lg)', ...glassStyle(theme, true) }}>
        <div style={{ width: 40, height: 5, borderRadius: 9, background: 'var(--hairline)', margin: '0 auto 12px' }} />
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16 }}>
          <h2 style={{ margin: 0, fontSize: 21, fontWeight: 800, color: 'var(--text)' }}>Ново място</h2>
          <button onClick={onClose} className="tap" style={{ background: 'var(--surface-2)', border: 'none', borderRadius: 20, width: 34, height: 34, cursor: 'pointer', color: 'var(--muted)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><IconClose size={18} /></button>
        </div>
        <div style={{ display: 'flex', gap: 10, marginBottom: 14 }}>
          {ICONS.map(([key, I]) => {
            const on = icon === key;
            return (
              <button key={key} onClick={() => setIcon(key)} className="tap" style={{ width: 54, height: 54, borderRadius: 15, cursor: 'pointer', border: on ? '2px solid var(--brand)' : '2px solid transparent', background: on ? 'color-mix(in oklch, var(--brand) 13%, transparent)' : 'var(--surface)', color: on ? 'var(--brand)' : 'var(--muted)', display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: on ? 'none' : 'var(--shadow)' }}><I size={23} /></button>
            );
          })}
        </div>
        <input value={label} onChange={(e) => setLabel(e.target.value)} placeholder="Име (напр. Вкъщи)" style={field} autoFocus />
        <input value={addr} onChange={(e) => setAddr(e.target.value)} placeholder="Адрес" style={field} />
        <PrimaryBtn onClick={() => valid && onAdd({ Icon: icon, label: label.trim(), addr: addr.trim() || 'Без адрес' })} style={{ marginTop: 6, opacity: valid ? 1 : 0.5, pointerEvents: valid ? 'auto' : 'none' }}>
          <IconCheck size={20} /> Запази
        </PrimaryBtn>
      </div>
    </div>
  );
}

// ============================================================
// ЕЗИК (Language picker)
// ============================================================
function LanguageScreen({ theme, go, lang, setLang }) {
  const { IconCheck } = window;
  const OPTS = [
    { code: 'bg', flag: 'БГ', name: 'Български', sub: 'Bulgarian' },
    { code: 'en', flag: 'EN', name: 'English', sub: 'Английски' },
  ];
  return (
    <SubShell theme={theme} title="Език" onBack={() => go('profile')}>
      <div style={{ background: 'var(--surface)', borderRadius: 18, margin: '6px 16px', boxShadow: 'var(--shadow)', overflow: 'hidden' }}>
        {OPTS.map((o, i) => {
          const on = lang === o.code;
          return (
            <div key={o.code} onClick={() => setLang(o.code)} className="tap" style={{ display: 'flex', alignItems: 'center', gap: 13, padding: '15px 15px', cursor: 'pointer', borderTop: i ? '0.5px solid var(--hairline)' : 'none' }}>
              <span style={{ width: 40, height: 40, borderRadius: 12, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: on ? 'var(--brand)' : 'var(--surface-2)', color: on ? '#fff' : 'var(--text)', fontSize: 14, fontWeight: 800 }}>{o.flag}</span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 16, fontWeight: 700 }}>{o.name}</div>
                <div style={{ fontSize: 13, color: 'var(--muted)', fontWeight: 500 }}>{o.sub}</div>
              </div>
              <span style={{ width: 24, height: 24, borderRadius: 24, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: on ? 'var(--brand)' : 'transparent', border: on ? 'none' : '2px solid var(--hairline)', color: '#fff' }}>{on && <IconCheck size={15} sw={2.6} />}</span>
            </div>
          );
        })}
      </div>
      <div style={{ fontSize: 13, color: 'var(--faint)', fontWeight: 500, padding: '12px 22px' }}>Езикът се прилага веднага в цялото приложение.</div>
    </SubShell>
  );
}

// ============================================================
// ПРЕДПОЧИТАНИЯ ЗА МАРШРУТ (Route preferences)
// ============================================================
function RoutePrefsScreen({ theme, go }) {
  const { IconShield, IconClock, IconBike, IconCheck, VSwitch } = window;
  const prefs = usePrefs();
  const STYLES = [
    { k: 'safe', Icon: IconShield, t: 'Най-безопасен', d: 'Защитени алеи и тихи улици, дори да отнема малко повече.' },
    { k: 'balanced', Icon: IconBike, t: 'Балансиран', d: 'Разумен баланс между безопасност и време.' },
    { k: 'fast', Icon: IconClock, t: 'Най-бърз', d: 'Възможно най-кратко време, повече булеварди.' },
  ];
  const TOGGLES = [
    { k: 'lanes', label: 'Предпочитай велоалеи' },
    { k: 'hills', label: 'Избягвай хълмове' },
    { k: 'traffic', label: 'Избягвай натоварени булеварди' },
    { k: 'lights', label: 'Избягвай неосветени улици' },
  ];
  return (
    <SubShell theme={theme} title="Предпочитания за маршрут" onBack={() => go('profile')}>
      <div style={{ padding: '2px 16px 0' }}>
        <SubLabel style={{ padding: '8px 6px 8px' }}>Стил на маршрута</SubLabel>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {STYLES.map((s) => {
            const on = prefs.style === s.k;
            return (
              <button key={s.k} onClick={() => PrefsStore.set((p) => ({ ...p, style: s.k }))} className="tap" style={{ display: 'flex', alignItems: 'center', gap: 13, padding: '14px 15px', borderRadius: 16, cursor: 'pointer', textAlign: 'left', background: on ? 'color-mix(in oklch, var(--brand) 9%, var(--surface))' : 'var(--surface)', border: on ? '2px solid var(--brand)' : '2px solid transparent', boxShadow: on ? 'none' : 'var(--shadow)', color: 'var(--text)' }}>
                <span style={{ width: 42, height: 42, borderRadius: 13, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: on ? 'var(--brand)' : 'var(--surface-2)', color: on ? '#fff' : 'var(--muted)' }}><s.Icon size={22} /></span>
                <span style={{ flex: 1, minWidth: 0 }}>
                  <span style={{ display: 'block', fontSize: 16, fontWeight: 700 }}>{s.t}</span>
                  <span style={{ display: 'block', fontSize: 13, color: 'var(--muted)', fontWeight: 500, lineHeight: 1.35, marginTop: 2 }}>{s.d}</span>
                </span>
                <span style={{ width: 24, height: 24, borderRadius: 24, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: on ? 'var(--brand)' : 'transparent', border: on ? 'none' : '2px solid var(--hairline)', color: '#fff' }}>{on && <IconCheck size={15} sw={2.6} />}</span>
              </button>
            );
          })}
        </div>
        <SubLabel>Допълнително</SubLabel>
        <div style={{ background: 'var(--surface)', borderRadius: 18, boxShadow: 'var(--shadow)', overflow: 'hidden' }}>
          {TOGGLES.map((tg, i) => (
            <div key={tg.k} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 15px', borderTop: i ? '0.5px solid var(--hairline)' : 'none' }}>
              <span style={{ flex: 1, fontSize: 15.5, fontWeight: 600 }}>{tg.label}</span>
              <VSwitch on={prefs[tg.k]} onChange={(v) => PrefsStore.set((p) => ({ ...p, [tg.k]: v }))} />
            </div>
          ))}
        </div>
      </div>
      <div style={{ fontSize: 13, color: 'var(--faint)', fontWeight: 500, padding: '14px 22px' }}>Тези настройки определят как Veloroute подрежда предложените маршрути.</div>
    </SubShell>
  );
}

// ============================================================
// ONBOARDING (Welcome / Permissions / Preferences)
// ============================================================
function OB_pill(label, color, bg) {
  return <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, padding: '4px 9px', borderRadius: 999, fontSize: 11.5, fontWeight: 700, color, background: bg }}>{label}</span>;
}

// real Sofia basemap embedded in an onboarding hero (static, non-interactive)
function HeroMap({ theme, community, route: showRoute, children }) {
  const { RealMap } = window;
  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>
        <RealMap theme={theme || 'light'} detail="standard" view="home"
          routeMode={showRoute ? 'plan' : 'none'} route={window.REAL_ROUTE}
          selected="safe" community={!!community} interactive={false} registerControls={false} />
      </div>
      {children}
    </div>
  );
}

function HeroWelcome({ theme }) {
  const { IconBike } = window;
  return (
    <HeroMap theme={theme} route>
      <div style={{ position: 'absolute', inset: 0, zIndex: 1000, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', background: 'radial-gradient(circle at 50% 42%, color-mix(in oklch, var(--surface) 45%, transparent), transparent 60%)' }}>
        <div style={{ width: 84, height: 84, borderRadius: 25, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', background: 'linear-gradient(140deg, var(--brand), color-mix(in oklch, var(--brand) 55%, #000))', boxShadow: '0 14px 30px color-mix(in oklch, var(--brand) 40%, transparent)' }}>
          <IconBike size={46} sw={1.9} />
        </div>
        <div style={{ marginTop: 13, fontSize: 15, fontWeight: 800, letterSpacing: 2, color: 'var(--brand)' }}>VELOROUTE</div>
      </div>
    </HeroMap>
  );
}

function HeroReport() {
  const { IconWarn, IconCar, IconBike, IconConstruction, IconBulb, IconCrash } = window;
  const cats = [
    { label: 'Дупка', Icon: IconWarn, level: 'danger' },
    { label: 'Опасно', Icon: IconCar, level: 'danger' },
    { label: 'Алея', Icon: IconBike, level: 'moderate' },
    { label: 'Ремонт', Icon: IconConstruction, level: 'moderate' },
    { label: 'Осветление', Icon: IconBulb, level: 'moderate' },
    { label: 'Инцидент', Icon: IconCrash, level: 'danger' },
  ];
  return (
    <div style={{ width: 250, display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 10 }}>
      {cats.map((c, i) => (
        <div key={i} style={{ background: 'var(--surface)', borderRadius: 15, padding: '13px 4px 9px', boxShadow: 'var(--shadow)', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 7, border: i === 0 ? '2px solid var(--danger)' : '2px solid transparent' }}>
          <span style={{ width: 40, height: 40, borderRadius: 12, display: 'flex', alignItems: 'center', justifyContent: 'center', background: `color-mix(in oklch, var(--${c.level}) 16%, transparent)`, color: `var(--${c.level})` }}><c.Icon size={22} /></span>
          <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--text)' }}>{c.label}</span>
        </div>
      ))}
    </div>
  );
}

function HeroSafety() {
  const { IconBike, IconCar } = window;
  const card = (tag, time, score, level, sub, sel) => (
    <div style={{ background: 'var(--surface)', borderRadius: 15, padding: '12px 13px', boxShadow: 'var(--shadow)', border: sel ? '2px solid var(--brand)' : '2px solid transparent' }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        {OB_pill(tag, level === 'safe' ? 'var(--safe)' : 'var(--moderate)', `color-mix(in oklch, var(--${level}) 16%, transparent)`)}
        <span style={{ fontSize: 18, fontWeight: 800 }}>{time}<span style={{ fontSize: 11, fontWeight: 600, color: 'var(--muted)' }}> мин</span></span>
      </div>
      <div style={{ marginTop: 9, display: 'flex', alignItems: 'center', gap: 9 }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, fontSize: 12.5, fontWeight: 700, color: `var(--${level})` }}>
          <span style={{ width: 7, height: 7, borderRadius: 9, background: `var(--${level})` }} /> {score}
        </span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: 12, fontWeight: 600, color: 'var(--muted)' }}>
          {level === 'safe' ? <IconBike size={14} /> : <IconCar size={14} />} {sub}
        </span>
      </div>
    </div>
  );
  return <div style={{ width: 250, display: 'flex', flexDirection: 'column', gap: 11 }}>{card('Най-безопасен', '15', 92, 'safe', '82% велоалеи', true)}{card('Най-бърз', '11', 64, 'moderate', 'висок трафик', false)}</div>;
}

function HeroAlerts() {
  const { IconArrowTurnL, IconWarn } = window;
  return (
    <div style={{ width: 252, display: 'flex', flexDirection: 'column', gap: 12 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 13, padding: '13px 15px', borderRadius: 18, color: '#fff', background: 'linear-gradient(150deg, var(--navline), color-mix(in oklch, var(--navline) 72%, #000))', boxShadow: '0 10px 24px color-mix(in oklch, var(--navline) 36%, transparent)' }}>
        <IconArrowTurnL size={40} sw={2.4} style={{ color: '#fff' }} />
        <div>
          <div style={{ fontSize: 26, fontWeight: 800, lineHeight: 1 }}>120<span style={{ fontSize: 13 }}> м</span></div>
          <div style={{ fontSize: 13.5, fontWeight: 700, marginTop: 2 }}>Завийте наляво</div>
          <div style={{ fontSize: 11.5, opacity: 0.85 }}>по бул. Васил Левски</div>
        </div>
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '11px 14px', borderRadius: 14, background: 'var(--danger)', color: '#fff', boxShadow: '0 8px 20px rgba(0,0,0,.2)', fontWeight: 700, fontSize: 13.5 }}>
        <IconWarn size={22} /> Неравен паваж напред
      </div>
    </div>
  );
}

function HeroCommunity({ theme }) {
  return (
    <HeroMap theme={theme} community>
      <div style={{ position: 'absolute', left: '50%', bottom: 14, zIndex: 1000, transform: 'translateX(-50%)', whiteSpace: 'nowrap', display: 'flex', alignItems: 'center', gap: 8, padding: '8px 14px', borderRadius: 999, background: 'var(--surface)', boxShadow: 'var(--shadow-lg)', fontSize: 12.5, fontWeight: 700, pointerEvents: 'none' }}>
        <span style={{ color: 'var(--brand)' }}>1 240</span> колоездачи <span style={{ color: 'var(--faint)' }}>·</span> <span style={{ color: 'var(--brand)' }}>128</span> сигнала
      </div>
    </HeroMap>
  );
}

// Onboarding hint that the map is filterable — by default it shows bike lanes + crossings, but
// the rider can switch on hazards, amenities, fountains and more from the legend.
function HeroFilters() {
  const { IconBike } = window;
  const chips = [
    { label: 'Велоалеи', v: 'route-lane', on: true },
    { label: 'Места за пресичане', v: 'safe', on: true },
    { label: 'Дупки и паваж', v: 'moderate', on: false },
    { label: 'Опасно движение', v: 'danger', on: false },
    { label: 'Велопаркинги', v: 'navline', on: false },
    { label: 'Чешми', v: 'safe', on: false },
  ];
  return (
    <div style={{ width: 252, display: 'flex', flexDirection: 'column', gap: 9 }}>
      {chips.map((c, i) => (
        <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '11px 13px', borderRadius: 13, background: 'var(--surface)', boxShadow: 'var(--shadow)', border: c.on ? '2px solid var(--brand)' : '2px solid transparent', opacity: c.on ? 1 : 0.72 }}>
          <span style={{ width: 14, height: 14, borderRadius: 7, background: `var(--${c.v})`, flexShrink: 0 }} />
          <span style={{ flex: 1, fontSize: 13.5, fontWeight: 700, color: 'var(--text)' }}>{c.label}</span>
          <span style={{ width: 34, height: 19, borderRadius: 12, background: c.on ? 'var(--brand)' : 'var(--hairline)', position: 'relative', flexShrink: 0 }}>
            <span style={{ position: 'absolute', top: 2, left: c.on ? 17 : 2, width: 15, height: 15, borderRadius: 9, background: '#fff', transition: 'left .2s', boxShadow: '0 1px 3px rgba(0,0,0,.25)' }} />
          </span>
        </div>
      ))}
    </div>
  );
}

const OB_FEATURES = [
  { tint: 'brand', Hero: HeroWelcome, title: 'Карай по-спокойно из София', sub: 'Veloroute подрежда маршрутите по безопасност и комфорт — не само по най-късото време.' },
  { tint: 'safe', Hero: HeroSafety, title: 'Виж безопасността, преди да тръгнеш', sub: 'Сравни маршрути по защитени алеи, трафик и наклон. Избери спокойствие или скорост — ти решаваш.' },
  { tint: 'navline', Hero: HeroAlerts, title: 'Навигация и сигнали в реално време', sub: 'Едри указания за един поглед и навременни предупреждения за дупки, паваж и опасно движение.' },
  { tint: 'brand', Hero: HeroCommunity, title: 'Картата, която колоездачите създават', sub: 'Хиляди местни рейдъри маркират безопасни улици и опасни участъци. Ти също можеш — и това прави маршрутите по-добри за всички.' },
  { tint: 'danger', Hero: HeroReport, title: 'Докладвай проблем с два тапа', sub: 'Дупка, опасно движение или блокирана алея — маркирай го за секунди и предупреди останалите колоездачи по пътя.' },
  { tint: 'navline', Hero: HeroFilters, title: 'Филтрирай картата както ти харесва', sub: 'По подразбиране показваме велоалеите и местата за пресичане. Включи опасности, велопаркинги, чешми и още — само нужното за теб.' },
];

function OnboardingScreen({ theme, go }) {
  const { IconCheck } = window;
  const TOTAL = 7;   // 6 feature slides + the preferences step
  const [step, setStep] = React.useState(0);
  const [prefs, setPrefs] = React.useState(['safe']);
  const togglePref = (k) => setPrefs((p) => p.includes(k) ? p.filter((x) => x !== k) : [...p, k]);

  const PREFS = [
    { k: 'safe', label: 'Най-безопасни маршрути' },
    { k: 'lanes', label: 'Предпочитай велоалеи' },
    { k: 'hills', label: 'Избягвай хълмове' },
    { k: 'traffic', label: 'Избягвай трафик' },
    { k: 'fast', label: 'Най-кратко време' },
  ];

  const next = () => { if (step < TOTAL - 1) setStep(step + 1); else go(needsAuthGate() ? 'auth' : 'home'); };
  const feat = OB_FEATURES[step];

  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 70, background: 'var(--bg)', display: 'flex', flexDirection: 'column' }}>
      {/* top bar: progress + skip */}
      <div style={{ padding: '56px 22px 0', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <div style={{ display: 'flex', gap: 6 }}>
          {Array.from({ length: TOTAL }).map((_, i) => (
            <span key={i} style={{ width: i === step ? 22 : 8, height: 8, borderRadius: 8, background: i === step ? 'var(--brand)' : 'var(--hairline)', transition: 'width .2s' }} />
          ))}
        </div>
        <button onClick={() => go(needsAuthGate() ? 'auth' : 'home')} className="tap" style={{ background: 'none', border: 'none', color: 'var(--muted)', fontSize: 15, fontWeight: 600, cursor: 'pointer' }}>Прескочи</button>
      </div>

      <div className="noscroll" style={{ flex: 1, overflowY: 'auto', padding: '18px 24px 10px', display: 'flex', flexDirection: 'column' }}>
        {feat && (
          <div style={{ display: 'flex', flexDirection: 'column', flex: 1 }}>
            <div style={{ height: 296, borderRadius: 26, position: 'relative', overflow: 'hidden', background: `color-mix(in oklch, var(--${feat.tint}) 10%, var(--surface))`, boxShadow: 'var(--shadow)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
              <feat.Hero theme={theme} />
            </div>
            <div style={{ marginTop: 30 }}>
              {step === 0 && <div style={{ fontSize: 13.5, fontWeight: 800, letterSpacing: 0.5, color: 'var(--brand)', marginBottom: 8 }}>ДОБРЕ ДОШЪЛ</div>}
              <h1 style={{ margin: 0, fontSize: 29, fontWeight: 800, lineHeight: 1.12, letterSpacing: -0.6, color: 'var(--text)', textWrap: 'balance' }}>{feat.title}</h1>
              <p style={{ fontSize: 16.5, color: 'var(--muted)', fontWeight: 500, lineHeight: 1.5, marginTop: 14 }}>{feat.sub}</p>
            </div>
          </div>
        )}

        {step === 6 && (
          <div>
            <h1 style={{ margin: '4px 0 8px', fontSize: 28, fontWeight: 800, letterSpacing: -0.5, color: 'var(--text)' }}>Как обичаш да караш?</h1>
            <p style={{ fontSize: 15.5, color: 'var(--muted)', fontWeight: 500, marginBottom: 20 }}>Ще подредим маршрутите спрямо теб. Може да смениш по-късно.</p>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              {PREFS.map((p) => {
                const on = prefs.includes(p.k);
                return (
                  <button key={p.k} onClick={() => togglePref(p.k)} className="tap" style={{
                    display: 'flex', alignItems: 'center', gap: 12, padding: '15px 16px', borderRadius: 15, cursor: 'pointer', textAlign: 'left',
                    background: on ? 'color-mix(in oklch, var(--brand) 9%, var(--surface))' : 'var(--surface)',
                    border: on ? '2px solid var(--brand)' : '2px solid transparent', boxShadow: on ? 'none' : 'var(--shadow)', color: 'var(--text)',
                  }}>
                    <span style={{ flex: 1, fontSize: 16, fontWeight: 700 }}>{p.label}</span>
                    <span style={{ width: 24, height: 24, borderRadius: 24, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: on ? 'var(--brand)' : 'transparent', border: on ? 'none' : '2px solid var(--hairline)', color: '#fff' }}>{on && <IconCheck size={15} sw={2.6} />}</span>
                  </button>
                );
              })}
            </div>
          </div>
        )}
      </div>

      <div style={{ padding: '10px 24px 30px', flexShrink: 0 }}>
        <PrimaryBtn onClick={next}>{step < TOTAL - 1 ? 'Напред' : 'Започни'}</PrimaryBtn>
        {step === 0 && (
          <div style={{ textAlign: 'center', marginTop: 14 }}>
            <span style={{ fontSize: 14.5, color: 'var(--muted)' }}>Вече имаш профил? </span>
            <button onClick={() => go('auth')} className="tap" style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 14.5, fontWeight: 800, color: 'var(--brand)' }}>Вход</button>
          </div>
        )}
      </div>
    </div>
  );
}

// ============================================================
// AUTH (Login / Register)
// ============================================================
// module-level so its identity is STABLE across renders — a component defined *inside* AuthScreen
// gets a new identity every keystroke, which remounts the <input> and steals focus (the "can only
// type one character" bug). Keep form-field components out of the render body.
function AuthField({ Icon, ph, value, onChange, type }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 11, height: 52, padding: '0 14px', borderRadius: 14, background: 'var(--surface-2)', marginBottom: 11, border: '1px solid var(--hairline)' }}>
      <Icon size={20} style={{ color: 'var(--faint)' }} />
      <input value={value} onChange={(e) => onChange(e.target.value)} placeholder={ph} type={type || 'text'} autoCapitalize="none" autoCorrect="off" autoComplete={type === 'password' ? 'current-password' : (type === 'email' ? 'email' : 'off')} style={{ flex: 1, border: 'none', background: 'none', outline: 'none', fontSize: 16, fontFamily: 'inherit', color: 'var(--text)' }} />
    </div>
  );
}

function AuthScreen({ theme, go, onAuthed }) {
  const { IconMail, IconLock, IconUser, IconBike } = window;
  const DB = window.VR_DB;
  const live = DB && DB.enabled;
  const [mode, setMode] = React.useState('register');
  const reg = mode === 'register';
  const forgot = mode === 'forgot';
  const [name, setName] = React.useState('');
  const [email, setEmail] = React.useState('');
  const [pass, setPass] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState('');
  const [info, setInfo] = React.useState('');

  const finish = (user) => { if (onAuthed) onAuthed(user); go('home'); };

  const sendReset = async () => {
    setErr(''); setInfo('');
    const e = email.trim();
    if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(e)) { setErr('Невалиден имейл адрес.'); return; }
    if (!live) { setInfo('Връзка за нулиране е изпратена (демо).'); return; }
    setBusy(true);
    const res = await DB.resetPassword(e);
    setBusy(false);
    if (res.error) { setErr(translateAuthErr(res.error)); return; }
    setInfo('Изпратихме връзка за нулиране на паролата на пощата ти. Отвори я, за да зададеш нова парола.');
  };

  const submit = async () => {
    setErr(''); setInfo('');
    if (forgot) { return sendReset(); }
    if (!live) { finish(null); return; }              // no backend → behave like the design demo
    const e = email.trim();
    if (!e || !pass) { setErr('Въведете имейл и парола.'); return; }
    if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(e)) { setErr('Невалиден имейл адрес.'); return; }
    if (reg && pass.length < 6) { setErr('Паролата трябва да е поне 6 символа.'); return; }
    setBusy(true);
    const res = reg ? await DB.signUp(e, pass, name.trim()) : await DB.signIn(e, pass);
    setBusy(false);
    if (res.error) { setErr(translateAuthErr(res.error)); return; }
    // signup with email-confirmation ON returns a user but NO session → must confirm before use
    if (reg && !res.session) {
      setInfo('Профилът е създаден. Потвърдете имейла си, после влезте. (Или изключете потвърждението в Supabase за моментален вход.)');
      setMode('login');
      return;
    }
    finish(res.user);
  };

  const google = async () => {
    setErr(''); setInfo('');
    if (!live) { setErr('Бекендът не е свързан.'); return; }
    setBusy(true);
    const res = await DB.signInWithGoogle();
    // on success the browser redirects to Google; onAuth picks up the session on return
    if (res.error) { setBusy(false); setErr(translateAuthErr(res.error)); return; }
  };

  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 70, background: 'var(--bg)', display: 'flex', flexDirection: 'column' }}>
      <div className="noscroll" style={{ flex: 1, overflowY: 'auto', padding: '70px 26px 20px' }}>
        <div style={{ width: 58, height: 58, borderRadius: 17, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', marginBottom: 20, background: 'linear-gradient(140deg, var(--brand), color-mix(in oklch, var(--brand) 55%, #000))' }}>
          <IconBike size={32} sw={1.9} />
        </div>
        <h1 style={{ margin: '0 0 6px', fontSize: 30, fontWeight: 800, letterSpacing: -0.6, color: 'var(--text)' }}>{forgot ? 'Забравена парола' : reg ? 'Създайте профил' : 'Добре дошли отново'}</h1>
        <p style={{ fontSize: 16, color: 'var(--muted)', fontWeight: 500, marginBottom: 26 }}>{forgot ? 'Въведете имейла си и ще изпратим връзка за нова парола.' : reg ? 'Присъединете се към колоездачите в София.' : 'Влезте, за да продължите.'}</p>

        {reg && <AuthField Icon={IconUser} ph="Име" value={name} onChange={setName} />}
        <AuthField Icon={IconMail} ph="Имейл" value={email} onChange={setEmail} type="email" />
        {!forgot && <AuthField Icon={IconLock} ph="Парола" value={pass} onChange={setPass} type="password" />}

        {!forgot && (
          <div style={{ textAlign: 'right', marginBottom: 6 }}>
            <button onClick={() => { setErr(''); setInfo(''); setMode('forgot'); }} className="tap" style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 13.5, fontWeight: 700, color: 'var(--brand)', padding: '2px 2px' }}>Забравена парола?</button>
          </div>
        )}

        {err && <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--danger)', margin: '2px 2px 8px' }}>{err}</div>}
        {info && <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--safe)', margin: '2px 2px 8px' }}>{info}</div>}

        <PrimaryBtn onClick={busy ? undefined : submit} style={{ marginTop: 6, opacity: busy ? 0.6 : 1 }}>{busy ? 'Момент…' : (forgot ? 'Изпрати връзка' : reg ? 'Регистрация' : 'Вход')}</PrimaryBtn>

        {forgot ? (
          <button onClick={() => { setErr(''); setInfo(''); setMode('login'); }} className="tap" style={{ width: '100%', background: 'none', border: 'none', cursor: 'pointer', fontSize: 14.5, fontWeight: 700, color: 'var(--muted)', padding: '16px 0 6px' }}>← Назад към вход</button>
        ) : (
          <React.Fragment>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, margin: '20px 0' }}>
              <div style={{ flex: 1, height: 1, background: 'var(--hairline)' }} />
              <span style={{ fontSize: 13, color: 'var(--faint)', fontWeight: 600 }}>или</span>
              <div style={{ flex: 1, height: 1, background: 'var(--hairline)' }} />
            </div>
            <button onClick={busy ? undefined : google} className="tap" style={{ width: '100%', height: 50, borderRadius: 14, border: '1px solid var(--hairline)', background: 'var(--surface)', cursor: 'pointer', fontSize: 15.5, fontWeight: 700, color: 'var(--text)', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 9 }}>
              <svg width="19" height="19" viewBox="0 0 48 48"><path fill="#FFC107" d="M43.6 20.5H42V20H24v8h11.3c-1.6 4.7-6.1 8-11.3 8a12 12 0 110-24c3 0 5.8 1.1 7.9 3l5.7-5.7A20 20 0 1024 44a20 20 0 0019.6-23.5z"/><path fill="#FF3D00" d="M6.3 14.7l6.6 4.8A12 12 0 0124 12c3 0 5.8 1.1 7.9 3l5.7-5.7A20 20 0 006.3 14.7z"/><path fill="#4CAF50" d="M24 44c5.2 0 9.9-2 13.4-5.2l-6.2-5.2A12 12 0 0124 36c-5.2 0-9.6-3.3-11.3-7.9l-6.5 5A20 20 0 0024 44z"/><path fill="#1976D2" d="M43.6 20.5H42V20H24v8h11.3a12 12 0 01-4.1 5.6l6.2 5.2C39.9 35.6 44 30.4 44 24c0-1.2-.1-2.4-.4-3.5z"/></svg>
              Продължи с Google</button>
          </React.Fragment>
        )}
      </div>
      {!forgot && (
      <div style={{ padding: '12px 26px 34px', flexShrink: 0, textAlign: 'center', borderTop: '0.5px solid var(--hairline)' }}>
        <span style={{ fontSize: 14.5, color: 'var(--muted)' }}>{reg ? 'Вече имате профил? ' : 'Нямате профил? '}</span>
        <button onClick={() => { setErr(''); setInfo(''); setMode(reg ? 'login' : 'register'); }} className="tap" style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 14.5, fontWeight: 800, color: 'var(--brand)' }}>{reg ? 'Вход' : 'Регистрация'}</button>
      </div>
      )}
    </div>
  );
}

function translateAuthErr(msg) {
  const m = (msg || '').toLowerCase();
  if (m.includes('not confirmed') || m.includes('not been confirmed')) return 'Имейлът не е потвърден. Проверете пощата си или изключете потвърждението в Supabase.';
  if (m.includes('invalid login') || m.includes('invalid credentials')) return 'Грешен имейл или парола.';
  if (m.includes('already registered') || m.includes('already been registered')) return 'Този имейл вече е регистриран — влезте вместо това.';
  if (m.includes('at least') || (m.includes('password') && m.includes('short'))) return 'Паролата трябва да е поне 6 символа.';
  if (m.includes('rate limit') || m.includes('too many')) return 'Твърде много опити. Опитайте по-късно.';
  if (m.includes('invalid') && m.includes('email')) return 'Невалиден имейл адрес.';
  return msg;
}

// ============================================================
// PASSWORD: set-new (recovery flow) + change (signed-in)
// ============================================================
function PasswordForm({ theme, title, subtitle, cta, onBack, onDone }) {
  const { IconLock, IconCheck } = window;
  const DB = window.VR_DB;
  const live = DB && DB.enabled;
  const [pass, setPass] = React.useState('');
  const [pass2, setPass2] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState('');
  const [done, setDone] = React.useState(false);
  const submit = async () => {
    setErr('');
    if (pass.length < 6) { setErr('Паролата трябва да е поне 6 символа.'); return; }
    if (pass !== pass2) { setErr('Паролите не съвпадат.'); return; }
    if (!live) { setDone(true); return; }
    setBusy(true);
    const res = await DB.updatePassword(pass);
    setBusy(false);
    if (res.error) { setErr(translateAuthErr(res.error)); return; }
    setDone(true);
  };
  return (
    <SubShell theme={theme} title={title} onBack={onBack}
      footer={done ? <PrimaryBtn onClick={onDone}><IconCheck size={20} /> Готово</PrimaryBtn>
                   : <PrimaryBtn onClick={busy ? undefined : submit} style={{ opacity: busy ? 0.6 : 1 }}>{busy ? 'Запазване…' : cta}</PrimaryBtn>}>
      {done ? (
        <div style={{ padding: '40px 30px', textAlign: 'center' }}>
          <div style={{ width: 72, height: 72, borderRadius: 72, margin: '0 auto 18px', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'color-mix(in oklch, var(--safe) 18%, transparent)', color: 'var(--safe)' }}><IconCheck size={40} sw={2.4} /></div>
          <div style={{ fontSize: 22, fontWeight: 800 }}>Паролата е сменена</div>
          <p style={{ fontSize: 15, color: 'var(--muted)', fontWeight: 500, lineHeight: 1.5, marginTop: 10 }}>Вече можеш да я ползваш при следващ вход.</p>
        </div>
      ) : (
        <div style={{ padding: '4px 22px' }}>
          <p style={{ fontSize: 15, color: 'var(--muted)', fontWeight: 500, lineHeight: 1.5, marginBottom: 18 }}>{subtitle}</p>
          <AuthField Icon={IconLock} ph="Нова парола" value={pass} onChange={setPass} type="password" />
          <AuthField Icon={IconLock} ph="Повтори паролата" value={pass2} onChange={setPass2} type="password" />
          {err && <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--danger)', margin: '2px 2px 8px' }}>{err}</div>}
        </div>
      )}
    </SubShell>
  );
}

function ResetPasswordScreen({ theme, go, onAuthed }) {
  return <PasswordForm theme={theme} title="Нова парола"
    subtitle="Задай нова парола за профила си."
    cta="Запази паролата" onBack={() => go('home')}
    onDone={() => { if (onAuthed && window.VR_DB) window.VR_DB.currentUser().then(onAuthed); go('home'); }} />;
}

function ChangePasswordScreen({ theme, go }) {
  return <PasswordForm theme={theme} title="Смяна на парола"
    subtitle="Въведи новата парола за профила си."
    cta="Смени паролата" onBack={() => go('profile')} onDone={() => go('profile')} />;
}

// ============================================================
// CONTRIBUTE (Add to map — community streets / dangerous places)
// ============================================================
function VSeg({ value, options, onChange }) {
  return (
    <div style={{ display: 'flex', gap: 4, padding: 4, borderRadius: 13, background: 'var(--surface-2)' }}>
      {options.map((o) => {
        const on = value === o.k;
        return (
          <button key={o.k} onClick={() => onChange(o.k)} className="tap" style={{
            flex: 1, height: 38, border: 'none', borderRadius: 10, cursor: 'pointer',
            fontSize: 13.5, fontWeight: 700, background: on ? 'var(--surface)' : 'transparent',
            color: on ? (o.color || 'var(--text)') : 'var(--muted)', boxShadow: on ? 'var(--shadow)' : 'none',
          }}>{o.label}</button>
        );
      })}
    </div>
  );
}
function VSwitch({ on, onChange }) {
  return (
    <button onClick={() => onChange(!on)} className="tap" style={{
      width: 50, height: 30, borderRadius: 30, border: 'none', cursor: 'pointer', padding: 3, flexShrink: 0,
      background: on ? 'var(--brand)' : 'var(--hairline)', display: 'flex', justifyContent: on ? 'flex-end' : 'flex-start',
    }}>
      <span style={{ width: 24, height: 24, borderRadius: 24, background: '#fff', boxShadow: '0 1px 3px rgba(0,0,0,.3)' }} />
    </button>
  );
}

const KINDS = {
  safe: ['Защитена велоалея', 'Спокойна улица', 'Добра настилка', 'Добро осветление', 'Зелен маршрут'],
  danger: ['Дупка', 'Лош паваж', 'Стъкло / отломки', 'Наводнение', 'Опасно кръстовище', 'Агресивно движение', 'Трамвайни релси', 'Стеснение'],
  point: ['Дупка', 'Произшествие', 'Лошо осветление', 'Блокирана алея', 'Строеж', 'Паднало дърво'],
};

function ContributeScreen({ theme, go, back, initialType, user, onSubmitted, pickMode, onEnterPick, onExitPick }) {
  const { IconShield, IconWarn, IconPin, IconCheck, IconMapPin2, IconClose, IconNavArrow, glassStyle } = window;
  const DB = window.VR_DB;
  const live = DB && DB.enabled;
  const goBack = back || (() => go('community'));
  const [type, setType] = React.useState(initialType || 'safe');
  const [kind, setKind] = React.useState(null);
  const [severity, setSeverity] = React.useState('mid');
  const [visibility, setVisibility] = React.useState('public');
  const [routing, setRouting] = React.useState(true);
  const [duration, setDuration] = React.useState('permanent');
  const [sent, setSent] = React.useState(false);
  const [loc, setLoc] = React.useState(null);     // [lat,lng] — the report's real coordinates
  const [area, setArea] = React.useState('');
  const [note, setNote] = React.useState('');
  const [gpsBusy, setGpsBusy] = React.useState(false);
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState('');
  const [locQ, setLocQ] = React.useState('');          // active typing in the location field
  const [suggest, setSuggest] = React.useState([]);     // geocode suggestions
  const [suggestBusy, setSuggestBusy] = React.useState(false);
  const curLevel = type === 'safe' ? 'safe' : (type === 'danger' ? 'danger' : 'moderate');
  const TYPES = [
    { k: 'safe', label: 'Безопасна улица', Icon: IconShield, level: 'safe' },
    { k: 'danger', label: 'Опасен участък', Icon: IconWarn, level: 'danger' },
    { k: 'point', label: 'Точков сигнал', Icon: IconPin, level: 'moderate' },
  ];
  // default the report location to wherever the map is centred (real Sofia coords)
  React.useEffect(() => {
    if (loc) return;
    const m = window.__vrMap;
    if (m) { const c = m.getCenter(); setLoc([c.lat, c.lng]); }
    else setLoc([42.6852, 23.3235]);
  }, []);
  const useGps = async () => {
    setGpsBusy(true); setErr('');
    try {
      const at = await window.getMyLocation();
      setLoc(at); setSuggest([]); setLocQ('');
      if (window.__vrShowUserLocation) window.__vrShowUserLocation(at[0], at[1]);
      if (window.__vrMap) window.__vrMap.panTo(at);
      if (window.reverseGeocode) { const lbl = await window.reverseGeocode(at[0], at[1]); if (lbl) setArea(lbl); }
    }
    catch (e) { setErr('Локацията не е достъпна. Преместете картата до мястото.'); }
    setGpsBusy(false);
  };
  // debounced geocoding of whatever the user types into the location field
  React.useEffect(() => {
    const query = locQ.trim();
    if (query.length < 2) { setSuggest([]); setSuggestBusy(false); return; }
    setSuggestBusy(true);
    const t = setTimeout(() => {
      window.geocodeSearch(query)
        .then((rs) => setSuggest(rs || []))
        .catch(() => setSuggest([]))
        .finally(() => setSuggestBusy(false));
    }, 300);
    return () => clearTimeout(t);
  }, [locQ]);
  const pickSuggest = (r) => {
    setLoc(r.at); setArea(r.name); setLocQ(''); setSuggest([]);
    if (window.__vrMap) window.__vrMap.panTo(r.at);
  };
  const confirmPick = async () => {
    const p = window.__vrPickedPoint;
    if (p) {
      setLoc([p.lat, p.lng]); setSuggest([]); setLocQ('');
      if (window.reverseGeocode) { const lbl = await window.reverseGeocode(p.lat, p.lng); if (lbl) setArea(lbl); }
    }
    onExitPick && onExitPick();
  };
  const locLabel = loc ? `${loc[0].toFixed(5)}, ${loc[1].toFixed(5)}` : '—';

  // map-pick mode — the form is hidden so the user can tap/drag the pin on the map behind.
  if (pickMode) {
    return (
      <div style={{ position: 'absolute', inset: 0, zIndex: 60, pointerEvents: 'none' }}>
        <div style={{ position: 'absolute', top: 64, left: 14, right: 14, pointerEvents: 'auto', borderRadius: 16, padding: '12px 16px', boxShadow: 'var(--shadow-lg)', ...glassStyle(theme, true) }}>
          <div style={{ fontSize: 15, fontWeight: 800, color: 'var(--text)' }}>Изберете местоположение</div>
          <div style={{ fontSize: 12.5, color: 'var(--muted)', fontWeight: 500, marginTop: 2 }}>Тапнете картата или преместете щифта, после „Готово“.</div>
        </div>
        <div style={{ position: 'absolute', left: 14, right: 14, bottom: 30, display: 'flex', gap: 10, pointerEvents: 'auto' }}>
          <button onClick={() => onExitPick && onExitPick()} className="tap" style={{ flex: 1, height: 52, borderRadius: 16, border: '1px solid var(--hairline)', background: 'var(--surface)', color: 'var(--text)', fontSize: 16, fontWeight: 700, cursor: 'pointer' }}>Откажи</button>
          <button onClick={confirmPick} className="tap" style={{ flex: 2, height: 52, borderRadius: 16, border: 'none', background: 'var(--brand)', color: '#fff', fontSize: 16.5, fontWeight: 800, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8 }}><IconCheck size={20} /> Готово</button>
        </div>
      </div>
    );
  }

  const publish = async () => {
    setErr('');
    if (!loc) { setErr('Изберете местоположение.'); return; }
    if (!live) { setErr('Бекендът не е свързан. Свържи се с поддръжката.'); return; }  // no fake success
    if (!user) { go('auth'); return; }                  // must be signed in to contribute
    setBusy(true);
    const label = kind || (type === 'safe' ? 'Безопасна улица' : type === 'danger' ? 'Опасен участък' : 'Сигнал');
    const res = await DB.submitReport({
      type, kind, severity, label, area, note,
      lat: loc[0], lng: loc[1], visibility, affects_routing: routing, duration,
    });
    setBusy(false);
    if (res.error === 'auth') { go('auth'); return; }
    if (res.error) { setErr('Неуспешно изпращане. Опитайте отново.'); return; }
    setSent(true);
    if (onSubmitted) onSubmitted();
  };

  if (sent) {
    return (
      <SubShell theme={theme} title="Добави към картата" onBack={goBack}>
        <div style={{ padding: '40px 30px', textAlign: 'center' }}>
          <div style={{ width: 72, height: 72, borderRadius: 72, margin: '0 auto 18px', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'color-mix(in oklch, var(--safe) 18%, transparent)', color: 'var(--safe)' }}><IconCheck size={40} sw={2.4} /></div>
          <div style={{ fontSize: 22, fontWeight: 800 }}>Изпратено!</div>
          <p style={{ fontSize: 15, color: 'var(--muted)', fontWeight: 500, lineHeight: 1.5, marginTop: 10 }}>
            {visibility === 'private'
              ? <>Записано <b style={{ color: 'var(--text)' }}>само за теб</b>. {routing ? 'Ще се отчита в твоите маршрути.' : 'Само като лична бележка — без влияние върху маршрути.'}</>
              : <>Появява се <b style={{ color: 'var(--text)' }}>пунктиран</b> на картата. Щом 3-ма колоездачи го потвърдят, става активен{routing ? ' и влияе на маршрутите' : ''}.</>}
          </p>
          <PrimaryBtn onClick={goBack} style={{ marginTop: 24 }}>Готово</PrimaryBtn>
        </div>
      </SubShell>
    );
  }
  return (
    <SubShell theme={theme} title="Добави към картата" onBack={goBack}
      footer={<PrimaryBtn onClick={busy ? undefined : publish} style={{ opacity: busy ? 0.6 : 1 }}>{busy ? 'Изпращане…' : 'Публикувай'}</PrimaryBtn>}>
      <p style={{ fontSize: 14.5, color: 'var(--muted)', fontWeight: 500, lineHeight: 1.5, padding: '4px 20px 16px' }}>
        Споделете каквото знаете за улиците в София. Приносите се проверяват от общността, преди да влияят на маршрутите.
      </p>
      <div style={{ padding: '0 16px' }}>
        <div style={{ display: 'flex', gap: 10, marginBottom: 18 }}>
          {TYPES.map((t) => {
            const on = type === t.k;
            return (
              <button key={t.k} onClick={() => setType(t.k)} className="tap" style={{
                flex: 1, cursor: 'pointer', borderRadius: 16, padding: '16px 6px', textAlign: 'center',
                background: on ? `color-mix(in oklch, var(--${t.level}) 12%, var(--surface))` : 'var(--surface)',
                border: on ? `2px solid var(--${t.level})` : '2px solid transparent', boxShadow: on ? 'none' : 'var(--shadow)', color: 'var(--text)',
                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 9,
              }}>
                <span style={{ width: 44, height: 44, borderRadius: 13, display: 'flex', alignItems: 'center', justifyContent: 'center', background: `color-mix(in oklch, var(--${t.level}) 16%, transparent)`, color: `var(--${t.level})` }}><t.Icon size={24} /></span>
                <span style={{ fontSize: 12.5, fontWeight: 700, lineHeight: 1.15 }}>{t.label}</span>
              </button>
            );
          })}
        </div>

        <div style={{ fontSize: 12.5, fontWeight: 700, letterSpacing: 0.3, color: 'var(--faint)', margin: '0 2px 8px' }}>{type === 'safe' ? 'КАКВО Е ДОБРОТО' : 'КАКЪВ Е ПРОБЛЕМЪТ'}</div>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginBottom: 18 }}>
          {(KINDS[type] || []).map((k) => {
            const on = kind === k;
            return (
              <button key={k} onClick={() => setKind(k)} className="tap" style={{
                padding: '8px 13px', borderRadius: 999, cursor: 'pointer', fontSize: 13.5, fontWeight: 700,
                border: on ? `1.5px solid var(--${curLevel})` : '1.5px solid var(--hairline)',
                background: on ? `color-mix(in oklch, var(--${curLevel}) 12%, transparent)` : 'var(--surface)',
                color: on ? `var(--${curLevel})` : 'var(--text)',
              }}>{k}</button>
            );
          })}
        </div>
        {(type === 'danger' || type === 'point') && (
          <div style={{ marginBottom: 18 }}>
            <div style={{ fontSize: 12.5, fontWeight: 700, letterSpacing: 0.3, color: 'var(--faint)', margin: '0 2px 8px' }}>СЕРИОЗНОСТ</div>
            <VSeg value={severity} onChange={setSeverity} options={[{ k: 'low', label: 'Ниска' }, { k: 'mid', label: 'Средна' }, { k: 'high', label: 'Висока', color: 'var(--danger)' }]} />
          </div>
        )}

        <div style={{ borderRadius: 16, background: 'var(--surface)', boxShadow: 'var(--shadow)', overflow: 'hidden', marginBottom: 14 }}>
          <div style={{ padding: 15 }}>
            <div style={{ fontSize: 12.5, fontWeight: 700, letterSpacing: 0.3, color: 'var(--faint)', marginBottom: 10 }}>МЕСТОПОЛОЖЕНИЕ</div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 11 }}>
              <span style={{ width: 40, height: 40, borderRadius: 11, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--surface-2)', color: 'var(--brand)' }}><IconMapPin2 size={21} /></span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <input value={area} onChange={(e) => { setArea(e.target.value); setLocQ(e.target.value); }} placeholder="Търси място (напр. бул. Витоша)" style={{ width: '100%', border: 'none', background: 'none', outline: 'none', fontSize: 15.5, fontWeight: 700, fontFamily: 'inherit', color: 'var(--text)' }} />
                <div style={{ fontSize: 12.5, color: 'var(--muted)', fontWeight: 500 }}>{loc ? `Избрано · ${locLabel}` : 'Изберете местоположение'}</div>
              </div>
              <button onClick={gpsBusy ? undefined : useGps} className="tap" style={{ height: 34, padding: '0 13px', borderRadius: 17, border: '1px solid var(--hairline)', background: 'var(--surface-2)', color: 'var(--text)', fontSize: 13, fontWeight: 700, cursor: 'pointer', flexShrink: 0 }}>{gpsBusy ? '…' : 'Тук съм'}</button>
            </div>
            {/* live geocode suggestions */}
            {(suggestBusy || suggest.length > 0) && (
              <div style={{ marginTop: 10, borderRadius: 12, border: '1px solid var(--hairline)', overflow: 'hidden' }}>
                {suggestBusy && suggest.length === 0 && <div style={{ padding: '10px 13px', fontSize: 13, color: 'var(--muted)', fontWeight: 500 }}>Търсене…</div>}
                {suggest.map((r, i) => (
                  <button key={r.name + '_' + i} onClick={() => pickSuggest(r)} className="tap" style={{ width: '100%', textAlign: 'left', display: 'flex', alignItems: 'center', gap: 10, padding: '10px 13px', border: 'none', background: 'var(--surface-2)', color: 'var(--text)', cursor: 'pointer', borderTop: i ? '0.5px solid var(--hairline)' : 'none' }}>
                    <IconPin size={17} style={{ color: 'var(--brand)', flexShrink: 0 }} />
                    <span style={{ flex: 1, minWidth: 0 }}>
                      <span style={{ display: 'block', fontSize: 14.5, fontWeight: 700, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{r.name}</span>
                      <span style={{ display: 'block', fontSize: 12, color: 'var(--muted)', fontWeight: 500, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{r.sub}</span>
                    </span>
                    {r.d && <span style={{ fontSize: 12, fontWeight: 600, color: 'var(--faint)', flexShrink: 0 }}>{r.d}</span>}
                  </button>
                ))}
              </div>
            )}
          </div>
          <button onClick={() => onEnterPick && onEnterPick()} className="tap" style={{ width: '100%', padding: '11px 15px', borderTop: '0.5px solid var(--hairline)', background: 'none', border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 9, color: 'var(--brand)', fontSize: 13.5, fontWeight: 700 }}>
            <IconNavArrow size={17} /> Избери на картата
          </button>
        </div>

        <div style={{ borderRadius: 16, background: 'var(--surface)', boxShadow: 'var(--shadow)', padding: '13px 15px' }}>
          <input value={note} onChange={(e) => setNote(e.target.value)} placeholder="Добавете бележка (по желание)…" style={{ width: '100%', border: 'none', background: 'none', outline: 'none', fontSize: 14.5, fontWeight: 500, fontFamily: 'inherit', color: 'var(--text)' }} />
        </div>
        {err && <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--danger)', margin: '10px 2px 0' }}>{err}</div>}
        {!user && live && <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--muted)', margin: '10px 2px 0' }}>Ще влезете в профила си при публикуване.</div>}

        <div style={{ fontSize: 12.5, fontWeight: 700, letterSpacing: 0.3, color: 'var(--faint)', margin: '18px 2px 8px' }}>НАСТРОЙКИ</div>
        <div style={{ borderRadius: 16, background: 'var(--surface)', boxShadow: 'var(--shadow)', overflow: 'hidden' }}>
          <div style={{ padding: '13px 15px' }}>
            <div style={{ fontSize: 15, fontWeight: 700, marginBottom: 9 }}>Видимост</div>
            <VSeg value={visibility} onChange={setVisibility} options={[{ k: 'public', label: 'Публично' }, { k: 'private', label: 'Само за мен' }]} />
            <div style={{ fontSize: 12.5, color: 'var(--muted)', fontWeight: 500, marginTop: 8 }}>{visibility === 'public' ? 'Вижда се от всички и помага на общността.' : 'Видимо само за теб — лична бележка по картата.'}</div>
          </div>
          <div style={{ padding: '13px 15px', borderTop: '0.5px solid var(--hairline)', display: 'flex', alignItems: 'center', gap: 12 }}>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 15, fontWeight: 700 }}>Отчитай в маршрутите</div>
              <div style={{ fontSize: 12.5, color: 'var(--muted)', fontWeight: 500 }}>{routing ? 'Влияе при изчисляване на маршрути.' : 'Само информативно — без влияние.'}</div>
            </div>
            <VSwitch on={routing} onChange={setRouting} />
          </div>
          <div style={{ padding: '13px 15px', borderTop: '0.5px solid var(--hairline)' }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 9 }}>
              <span style={{ fontSize: 15, fontWeight: 700 }}>Срок</span>
              {duration === 'temporary' && <span style={{ fontSize: 12.5, color: 'var(--brand)', fontWeight: 700 }}>изтича след 7 дни</span>}
            </div>
            <VSeg value={duration} onChange={setDuration} options={[{ k: 'permanent', label: 'Постоянно' }, { k: 'temporary', label: 'Временно' }]} />
          </div>
        </div>
      </div>
    </SubShell>
  );
}

function PremiumScreen({ theme, go }) {
  const { IconShield, IconElevation, IconClock, IconBike, IconSound, IconCheck } = window;
  const feats = [
    { Icon: IconShield, t: 'Офлайн карти', d: 'Карти за цяла България без интернет.' },
    { Icon: IconElevation, t: 'Разширени анализи', d: 'Темпо, наклон, безопасност след всяко каране.' },
    { Icon: IconClock, t: 'Пълна история', d: 'Всичките ти пътувания, без ограничение.' },
    { Icon: IconBike, t: 'Умни препоръки', d: '„Най-безопасен маршрут след 18:00“.' },
    { Icon: IconSound, t: 'Smartwatch', d: 'Навигация на китката ти.' },
  ];
  return (
    <SubShell theme={theme} title="Veloroute+" onBack={() => go('profile')}
      footer={<PrimaryBtn onClick={() => go('profile')}>Активирай Veloroute+</PrimaryBtn>}>
      <div style={{ margin: '0 16px 16px', borderRadius: 22, padding: '22px 20px', color: '#fff', background: 'linear-gradient(135deg, oklch(0.55 0.13 250), oklch(0.5 0.15 285))', boxShadow: '0 12px 30px oklch(0.5 0.13 260 / 0.4)' }}>
        <div style={{ fontSize: 26, fontWeight: 800 }}>Veloroute+</div>
        <div style={{ fontSize: 14.5, opacity: 0.9, fontWeight: 500, marginTop: 4 }}>7 дни безплатно, после 9,99 лв./мес.</div>
      </div>
      <div style={{ background: 'var(--surface)', borderRadius: 18, margin: '0 16px', boxShadow: 'var(--shadow)', overflow: 'hidden' }}>
        {feats.map((f, i) => (
          <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 13, padding: '14px 15px', borderTop: i ? '0.5px solid var(--hairline)' : 'none' }}>
            <span style={{ width: 38, height: 38, borderRadius: 11, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'color-mix(in oklch, var(--navline) 13%, transparent)', color: 'var(--navline)' }}><f.Icon size={20} /></span>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 15.5, fontWeight: 700 }}>{f.t}</div>
              <div style={{ fontSize: 13, color: 'var(--muted)', fontWeight: 500 }}>{f.d}</div>
            </div>
            <IconCheck size={20} style={{ color: 'var(--safe)' }} />
          </div>
        ))}
      </div>
    </SubShell>
  );
}

function BikeScreen({ theme, go }) {
  const { IconCheck } = window;
  const [bike, setBike] = React.useState('Градски');
  const OPTS = ['Градски', 'Шосеен', 'Електрически', 'Сгъваем'];
  return (
    <SubShell theme={theme} title="Моят велосипед" onBack={() => go('profile')}
      footer={<PrimaryBtn onClick={() => go('profile')}>Запази</PrimaryBtn>}>
      <div style={{ fontSize: 13, color: 'var(--faint)', fontWeight: 700, letterSpacing: 0.3, padding: '4px 22px 10px' }}>ТИП ВЕЛОСИПЕД</div>
      <div style={{ background: 'var(--surface)', borderRadius: 18, margin: '0 16px', boxShadow: 'var(--shadow)', overflow: 'hidden' }}>
        {OPTS.map((o, i) => (
          <button key={o} onClick={() => setBike(o)} className="tap" style={{ width: '100%', display: 'flex', alignItems: 'center', gap: 12, padding: '15px 16px', cursor: 'pointer', border: 'none', background: 'none', color: 'var(--text)', borderTop: i ? '0.5px solid var(--hairline)' : 'none' }}>
            <span style={{ flex: 1, textAlign: 'left', fontSize: 16, fontWeight: 700 }}>{o}</span>
            {bike === o && <IconCheck size={20} style={{ color: 'var(--brand)' }} />}
          </button>
        ))}
      </div>
      <div style={{ fontSize: 13, color: 'var(--faint)', fontWeight: 500, padding: '12px 22px' }}>Влияе на скоростта и наклоните при изчисляване на маршрут.</div>
    </SubShell>
  );
}

function NotificationsScreen({ theme, go }) {
  const [on, setOn] = React.useState({ hazards: true, route: true, community: true, weekly: false });
  const ITEMS = [
    { k: 'hazards', t: 'Опасности по пътя', d: 'Сигнали при дупки, паваж и опасно движение.' },
    { k: 'route', t: 'Промени в маршрута', d: 'Известия при по-добър или по-безопасен маршрут.' },
    { k: 'community', t: 'Общностни сигнали', d: 'Нови сигнали около теб.' },
    { k: 'weekly', t: 'Седмичен отчет', d: 'Резюме на твоите пътувания.' },
  ];
  return (
    <SubShell theme={theme} title="Известия" onBack={() => go('profile')}>
      <div style={{ background: 'var(--surface)', borderRadius: 18, margin: '6px 16px', boxShadow: 'var(--shadow)', overflow: 'hidden' }}>
        {ITEMS.map((it, i) => (
          <div key={it.k} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 15px', borderTop: i ? '0.5px solid var(--hairline)' : 'none' }}>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 15.5, fontWeight: 700 }}>{it.t}</div>
              <div style={{ fontSize: 12.5, color: 'var(--muted)', fontWeight: 500 }}>{it.d}</div>
            </div>
            <VSwitch on={on[it.k]} onChange={(v) => setOn((s) => ({ ...s, [it.k]: v }))} />
          </div>
        ))}
      </div>
    </SubShell>
  );
}

Object.assign(window, {
  ReportSheet, SavedPlacesScreen, AddPlaceSheet, LanguageScreen, RoutePrefsScreen,
  OnboardingScreen, AuthScreen, ContributeScreen, PremiumScreen, BikeScreen, NotificationsScreen,
  ResetPasswordScreen, ChangePasswordScreen,
  VSwitch, SubShell, PrimaryBtn, SubLabel,
  SavedStore, Saved, useSaved, PrefsStore, usePrefs, STYLE_LABEL,
  VoicePref, useVoicePref,
  SavedRoutesStore, SavedRoutes, useSavedRoutes,
  RecentStore, Recents, useRecents, TripsStore, Trips, useTrips, vrWhen,
  CommStore, Comm, useComm, isOfficial,
  UserStore, useUser, vrDisplayName, vrInitials,
});
