/* screens.jsx — экраны приложения: Записи, Поиск, Напоминания, Вход. */

function EmptyState({ icon = "inbox", title, sub, action }) {
  return (
    <div className="flex flex-col items-center justify-center text-center py-20 px-6">
      <div className="grid place-items-center w-16 h-16 rounded-2xl bg-[var(--surface-2)] border border-[var(--border)] text-[var(--muted)] mb-4">
        <Icon name={icon} size={28} strokeWidth={1.5} />
      </div>
      <h3 className="text-[17px] font-bold text-[var(--text)]">{title}</h3>
      {sub && <p className="mt-1.5 max-w-xs text-sm text-[var(--muted)] leading-relaxed">{sub}</p>}
      {action && <div className="mt-5">{action}</div>}
    </div>
  );
}

function NotesScreen({ onOpenNote, onNew, reloadKey }) {
  const cats = Store.useCategories();
  const [notes, setNotes] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [category, setCategory] = React.useState("all");
  const [q, setQ] = React.useState("");
  const [activeTag, setActiveTag] = React.useState(null);
  const [view, setView] = React.useState("active"); // active | archived | trash

  const load = React.useCallback(async () => {
    setLoading(true);
    const data = await api.getNotes({ category, q: q || undefined, tag: activeTag || undefined, view });
    setNotes(data);
    setLoading(false);
  }, [category, q, activeTag, view]);

  React.useEffect(() => { load(); }, [category, activeTag, view, reloadKey]);
  React.useEffect(() => {
    const t = setTimeout(load, 250);
    return () => clearTimeout(t);
  }, [q]);

  const allTags = React.useMemo(() => {
    const s = new Set();
    notes.forEach((n) => n.tags.forEach((t) => s.add(t)));
    return [...s];
  }, [notes]);

  const onAction = async (note, action) => {
    if (action === "pin") await api.pinNote(note.id, !note.pinned);
    else if (action === "archive") await api.archiveNote(note.id, true);
    else if (action === "unarchive") await api.archiveNote(note.id, false);
    else if (action === "trash") await api.deleteNote(note.id);
    else if (action === "restore") await api.restoreNote(note.id);
    else if (action === "purge") await api.purgeNote(note.id);
    load();
  };

  const emptyTrash = async () => { await api.emptyTrash(); load(); };

  const chips = [{ key: "all", label: "Все", color: null }, ...cats];
  const filtering = q || category !== "all" || activeTag;

  // группировка по датам (для активных)
  const groups = React.useMemo(() => groupByDate(notes, view), [notes, view]);

  const viewTabs = [
    { v: "active", label: "Активные", icon: "notes" },
    { v: "archived", label: "Архив", icon: "inbox" },
    { v: "trash", label: "Корзина", icon: "trash" },
  ];

  return (
    <div>
      <ScreenHead title="Записи" sub="Лента всех мыслей, задач и заметок">
        <Button onClick={onNew} className="hidden sm:inline-flex"><Icon name="plus" size={17} /> Новая запись</Button>
      </ScreenHead>

      {/* вид: активные / архив / корзина */}
      <div className="flex items-center gap-2 mb-3 overflow-x-auto -mx-1 px-1">
        <div className="inline-flex p-0.5 rounded-xl bg-[var(--surface-2)] border border-[var(--border)] shrink-0">
          {viewTabs.map((t) => (
            <button key={t.v} onClick={() => setView(t.v)}
              className={`inline-flex items-center gap-1.5 px-3 h-8 rounded-[10px] text-[13px] font-semibold whitespace-nowrap transition ${view === t.v ? "bg-[var(--surface)] text-[var(--text)] shadow-[0_1px_4px_var(--shadow)]" : "text-[var(--muted)] hover:text-[var(--text)]"}`}>
              <Icon name={t.icon} size={15} /> {t.label}
            </button>
          ))}
        </div>
        {view === "trash" && notes.length > 0 && (
          <button onClick={emptyTrash} className="ml-auto shrink-0 text-[13px] font-semibold text-[var(--danger)] hover:underline">Очистить корзину</button>
        )}
      </div>

      {view === "trash" && (
        <p className="mb-3 text-[12px] text-[var(--muted)] inline-flex items-center gap-1.5"><Icon name="trash" size={13} /> Удалённое хранится 30 дней, потом исчезает само.</p>
      )}

      <div className="relative mb-3">
        <Icon name="search" size={18} className="absolute left-3.5 top-1/2 -translate-y-1/2 text-[var(--muted)]" />
        <input
          value={q}
          onChange={(e) => setQ(e.target.value)}
          placeholder="Быстрый поиск по тексту…"
          className="w-full h-11 rounded-xl border border-[var(--border)] bg-[var(--surface)] pl-10 pr-3 text-sm text-[var(--text)] outline-none focus:border-[var(--accent)] transition placeholder:text-[var(--muted)]"
        />
      </div>

      <div className="flex flex-wrap items-center gap-2 mb-2">
        {chips.map((c) => {
          const active = category === c.key;
          return (
            <button
              key={c.key}
              onClick={() => setCategory(c.key)}
              className={`filter-chip ${active ? "filter-chip-on" : ""} ${c.color && active ? Store.colorClass(c.color) : ""}`}
            >
              {c.key !== "all" && <span className={`cat-dot ${active ? "" : "dot-" + c.color}`} />}
              {c.label}
            </button>
          );
        })}
      </div>

      {allTags.length > 0 && (
        <div className="flex flex-wrap items-center gap-1.5 mb-5">
          <span className="text-[12px] text-[var(--muted)] inline-flex items-center gap-1"><Icon name="tag" size={13} /> Теги:</span>
          {activeTag && (
            <button onClick={() => setActiveTag(null)} className="text-[11px] rounded-full px-2 py-0.5 bg-[var(--accent-weak)] text-[var(--accent)] font-semibold inline-flex items-center gap-1">
              #{activeTag} <Icon name="close" size={11} strokeWidth={2.4} />
            </button>
          )}
          {!activeTag && allTags.slice(0, 10).map((t) => (
            <button key={t} onClick={() => setActiveTag(t)} className="text-[11px] rounded-full px-2 py-0.5 bg-[var(--surface-2)] border border-[var(--border)] text-[var(--muted)] hover:text-[var(--text)] hover:border-[var(--border-strong)] transition">#{t}</button>
          ))}
        </div>
      )}

      {loading ? (
        <div className="grid gap-3 sm:gap-3.5">{[0,1,2,3].map((i) => <SkeletonCard key={i} />)}</div>
      ) : notes.length === 0 ? (
        <EmptyState
          icon={view === "trash" ? "trash" : view === "archived" ? "inbox" : "notes"}
          title={filtering ? "Ничего не нашлось" : view === "trash" ? "Корзина пуста" : view === "archived" ? "В архиве пусто" : "Здесь пока пусто"}
          sub={filtering ? "Попробуй изменить фильтры или поисковый запрос." : view === "active" ? "Добавь первую запись — мысль, задачу или идею. Остальное ИИ разложит сам." : ""}
          action={!filtering && view === "active" && <Button onClick={onNew}><Icon name="plus" size={17} /> Добавить запись</Button>}
        />
      ) : (
        <div className="space-y-5">
          {groups.map((g) => (
            <div key={g.key}>
              {g.label && <h3 className="text-[12px] font-bold uppercase tracking-wide text-[var(--muted)] mb-2.5 px-0.5">{g.label}</h3>}
              <div className="grid gap-3 sm:gap-3.5">
                {g.items.map((n, i) => <NoteCard key={n.id} note={n} index={i} view={view} onOpen={onOpenNote} onAction={onAction} />)}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// группировка ленты по датам: Закреплённые / Сегодня / Вчера / На этой неделе / Раньше
function groupByDate(notes, view) {
  if (view !== "active") return [{ key: "all", label: null, items: notes }];
  const pinned = notes.filter((n) => n.pinned);
  const rest = notes.filter((n) => !n.pinned);
  const buckets = { today: [], yesterday: [], week: [], older: [] };
  const now = new Date();
  const sod = (d) => { const x = new Date(d); x.setHours(0, 0, 0, 0); return x; };
  rest.forEach((n) => {
    const diff = Math.round((sod(now) - sod(n.created_at)) / 86400e3);
    if (diff <= 0) buckets.today.push(n);
    else if (diff === 1) buckets.yesterday.push(n);
    else if (diff < 7) buckets.week.push(n);
    else buckets.older.push(n);
  });
  const out = [];
  if (pinned.length) out.push({ key: "pinned", label: "📌 Закреплённые", items: pinned });
  if (buckets.today.length) out.push({ key: "today", label: "Сегодня", items: buckets.today });
  if (buckets.yesterday.length) out.push({ key: "yesterday", label: "Вчера", items: buckets.yesterday });
  if (buckets.week.length) out.push({ key: "week", label: "На этой неделе", items: buckets.week });
  if (buckets.older.length) out.push({ key: "older", label: "Раньше", items: buckets.older });
  return out;
}

function SearchScreen({ onOpenNote }) {
  const [mode, setMode] = React.useState("search");
  const [query, setQuery] = React.useState("");
  const [state, setState] = React.useState("idle");
  const [res, setRes] = React.useState({ answer: null, results: [] });
  const ref = React.useRef(null);

  React.useEffect(() => { ref.current && ref.current.focus(); }, []);

  const run = async (qOverride) => {
    const text = ((qOverride != null ? qOverride : query) || "").trim();
    if (!text) return;
    if (text !== query) setQuery(text);
    setState("loading");
    const data = await api.search({ query: text });
    setRes(data);
    setState("done");
  };

  const suggestions = ["что у меня по работе на этой неделе", "напоминания про здоровье", "идеи для продукта", "что купить"];

  return (
    <div>
      <ScreenHead title="Поиск и чат" sub={mode === "chat" ? "Спроси что угодно по своим записям — ИИ ответит на основе твоей базы" : "Найди по смыслу — не только по словам"} />

      <div className="inline-flex p-0.5 rounded-xl bg-[var(--surface-2)] border border-[var(--border)] mb-4">
        {[{ v: "search", label: "Поиск", icon: "search" }, { v: "chat", label: "Чат с заметками", icon: "sparkles" }].map((t) => (
          <button key={t.v} onClick={() => setMode(t.v)}
            className={`inline-flex items-center gap-1.5 px-3.5 h-9 rounded-[10px] text-[13px] font-semibold transition ${mode === t.v ? "bg-[var(--surface)] text-[var(--text)] shadow-[0_1px_4px_var(--shadow)]" : "text-[var(--muted)] hover:text-[var(--text)]"}`}>
            <Icon name={t.icon} size={15} /> {t.label}
          </button>
        ))}
      </div>

      {mode === "chat" ? <ChatView onOpenNote={onOpenNote} /> : (
      <div>
      <div className="relative">
        <div className="flex items-center gap-2 rounded-2xl border-2 border-[var(--border)] bg-[var(--surface)] focus-within:border-[var(--accent)] transition px-3 sm:px-4 py-2 shadow-[0_4px_20px_-14px_var(--shadow)]">
          <Icon name="sparkles" size={20} className="text-[var(--accent)] shrink-0" />
          <input
            ref={ref}
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            onKeyDown={(e) => e.key === "Enter" && run()}
            placeholder="Спроси или найди по смыслу…"
            className="flex-1 bg-transparent outline-none py-1.5 text-[15px] sm:text-base text-[var(--text)] placeholder:text-[var(--muted)]"
          />
          <Button onClick={run} disabled={!query.trim() || state === "loading"} className="shrink-0">
            {state === "loading" ? <Spinner /> : <Icon name="arrowRight" size={17} />}
            <span className="hidden sm:inline">Найти</span>
          </Button>
        </div>
      </div>

      {state === "idle" && (
        <div className="mt-4 flex flex-wrap gap-2">
          <span className="text-[12px] text-[var(--muted)] self-center">Например:</span>
          {suggestions.map((s) => (
            <button key={s} onClick={() => run(s)} className="text-[13px] rounded-full px-3 py-1.5 bg-[var(--surface-2)] border border-[var(--border)] text-[var(--muted)] hover:text-[var(--text)] hover:border-[var(--border-strong)] transition">{s}</button>
          ))}
        </div>
      )}

      {state === "loading" && (
        <div className="mt-6 space-y-3">
          <div className="sk h-24 rounded-2xl" />
          {[0,1].map((i) => <SkeletonCard key={i} />)}
        </div>
      )}

      {state === "done" && (
        <div className="mt-6">
          {res.answer && (
            <div className="answer-card card-in rounded-2xl p-4 sm:p-5 mb-5">
              <div className="flex items-center gap-2 mb-2 text-[var(--accent)]">
                <Icon name="sparkles" size={17} />
                <span className="text-[12px] font-bold uppercase tracking-wide whitespace-nowrap">Ответ ИИ</span>
              </div>
              <p className="text-[15px] leading-relaxed text-[var(--text)]" style={{ textWrap: "pretty" }}>{res.answer}</p>
            </div>
          )}
          {res.results.length === 0 ? (
            <EmptyState icon="search" title="Ничего не нашлось" sub="Попробуй переформулировать запрос другими словами." />
          ) : (
            <>
              <p className="text-[12px] font-semibold uppercase tracking-wide text-[var(--muted)] mb-3">
                Найдено записей: {res.results.length}
              </p>
              <div className="grid gap-3 sm:gap-3.5">
                {res.results.map((n, i) => <NoteCard key={n.id} note={n} index={i} onOpen={onOpenNote} />)}
              </div>
            </>
          )}
        </div>
      )}
      </div>
      )}
    </div>
  );
}

/* ----------------------------------------------------------- ЧАТ С ЗАМЕТКАМИ */
function ChatView({ onOpenNote }) {
  const [messages, setMessages] = React.useState([
    { role: "ai", text: "Привет! Я знаю всё, что ты записал. Спроси, например: «что у меня по работе?» или «собери все идеи».", sources: [] },
  ]);
  const [input, setInput] = React.useState("");
  const [busy, setBusy] = React.useState(false);
  const endRef = React.useRef(null);

  React.useEffect(() => { if (endRef.current) endRef.current.scrollIntoView({ block: "nearest" }); }, [messages, busy]);

  const send = async (text) => {
    const msg = (text || input).trim();
    if (!msg || busy) return;
    setInput("");
    setMessages((m) => [...m, { role: "user", text: msg }]);
    setBusy(true);
    const res = await api.chat({ message: msg, history: messages });
    setMessages((m) => [...m, { role: "ai", text: res.answer, sources: res.sources || [] }]);
    setBusy(false);
  };

  const chips = ["что у меня по работе?", "собери все идеи", "что нужно купить", "напомни про здоровье"];

  return (
    <div className="flex flex-col" style={{ minHeight: "min(60vh, 520px)" }}>
      <div className="flex-1 space-y-3 mb-3">
        {messages.map((m, i) => (
          <div key={i} className={`flex ${m.role === "user" ? "justify-end" : "justify-start"}`}>
            <div className={`max-w-[85%] rounded-2xl px-4 py-2.5 ${m.role === "user" ? "bg-[var(--accent)] text-white rounded-br-md" : "bg-[var(--surface)] border border-[var(--border)] text-[var(--text)] rounded-bl-md"}`}>
              <p className="text-[14px] leading-relaxed whitespace-pre-wrap" style={{ textWrap: "pretty" }}>{m.text}</p>
              {m.sources && m.sources.length > 0 && (
                <div className="mt-2.5 pt-2.5 border-t border-[var(--border)] grid gap-1.5">
                  {m.sources.map((s) => (
                    <button key={s.id} onClick={() => onOpenNote(s)} className="text-left flex items-center gap-2 text-[12px] text-[var(--muted)] hover:text-[var(--accent)] transition">
                      <span className={`w-2 h-2 rounded-full shrink-0 dot-${catFrom(s.category).color}`} />
                      <span className="truncate">{s.summary || s.raw_text}</span>
                    </button>
                  ))}
                </div>
              )}
            </div>
          </div>
        ))}
        {busy && (
          <div className="flex justify-start">
            <div className="rounded-2xl rounded-bl-md bg-[var(--surface)] border border-[var(--border)] px-4 py-3">
              <span className="typing-dots"><i></i><i></i><i></i></span>
            </div>
          </div>
        )}
        <div ref={endRef} />
      </div>

      {messages.length <= 1 && (
        <div className="flex flex-wrap gap-2 mb-3">
          {chips.map((c) => (
            <button key={c} onClick={() => send(c)} className="text-[13px] rounded-full px-3 py-1.5 bg-[var(--surface-2)] border border-[var(--border)] text-[var(--muted)] hover:text-[var(--text)] hover:border-[var(--border-strong)] transition">{c}</button>
          ))}
        </div>
      )}

      <div className="sticky bottom-2 flex items-center gap-2 rounded-2xl border border-[var(--border)] bg-[var(--surface)] px-3 py-2 shadow-[0_4px_20px_-14px_var(--shadow)]">
        <input value={input} onChange={(e) => setInput(e.target.value)} onKeyDown={(e) => e.key === "Enter" && send()}
          placeholder="Спроси по своим заметкам…"
          className="flex-1 bg-transparent outline-none py-1.5 text-[15px] text-[var(--text)] placeholder:text-[var(--muted)]" />
        <Button onClick={() => send()} disabled={!input.trim() || busy} size="sm">
          {busy ? <Spinner size={15} /> : <Icon name="arrowRight" size={16} />}
        </Button>
      </div>
    </div>
  );
}

function RemindersScreen({ onOpenNote, reloadKey, onChanged }) {
  const [items, setItems] = React.useState([]);
  const [loading, setLoading] = React.useState(true);

  const load = React.useCallback(async () => {
    setLoading(true);
    const data = await api.getReminders();
    setItems(data);
    setLoading(false);
  }, []);
  React.useEffect(() => { load(); }, [reloadKey]);

  const upcoming = items.filter((r) => r.status === "pending").sort((a, b) => new Date(a.remind_at) - new Date(b.remind_at));
  const past = items.filter((r) => r.status !== "pending").sort((a, b) => new Date(b.remind_at) - new Date(a.remind_at));

  const cancel = async (r) => { await api.updateReminder(r.id, { status: "cancelled" }); await load(); onChanged && onChanged(); };
  const done = async (r) => { await api.updateReminder(r.id, { status: "done" }); await load(); onChanged && onChanged(); };
  const snooze = async (r, days) => {
    const base = new Date(r.remind_at);
    const now = new Date();
    const from = base > now ? base : now;
    from.setDate(from.getDate() + days);
    await api.updateReminder(r.id, { remind_at: from.toISOString(), status: "pending" });
    await load(); onChanged && onChanged();
  };
  const openNote = async (r) => {
    const list = await api.getNotes({});
    const n = list.find((x) => x.id === r.note_id);
    if (n) onOpenNote(n);
  };

  return (
    <div>
      <ScreenHead title="Напоминания" sub="Все напоминания по ближайшему времени" />
      {loading ? (
        <div className="space-y-3">{[0,1,2].map((i) => <div key={i} className="sk h-16 rounded-2xl" />)}</div>
      ) : items.length === 0 ? (
        <EmptyState icon="bell" title="Напоминаний нет" sub="Когда добавишь дату к записи — оно появится здесь." />
      ) : (
        <div className="space-y-7">
          <ReminderGroup title="Предстоящие" count={upcoming.length} items={upcoming} onCancel={cancel} onDone={done} onSnooze={snooze} onOpen={openNote} />
          {past.length > 0 && <ReminderGroup title="Прошедшие" count={past.length} items={past} onCancel={cancel} onDone={done} onSnooze={snooze} onOpen={openNote} muted />}
        </div>
      )}
    </div>
  );
}

function ReminderGroup({ title, count, items, onCancel, onDone, onSnooze, onOpen, muted }) {
  if (items.length === 0)
    return (
      <div>
        <GroupHead title={title} count={0} />
        <p className="text-sm text-[var(--muted)] px-1">Пусто</p>
      </div>
    );
  return (
    <div>
      <GroupHead title={title} count={count} />
      <div className="grid gap-2.5">
        {items.map((r) => <ReminderCard key={r.id} r={r} onCancel={onCancel} onDone={onDone} onSnooze={onSnooze} onOpen={onOpen} muted={muted} />)}
      </div>
    </div>
  );
}

function GroupHead({ title, count }) {
  return (
    <div className="flex items-center gap-2 mb-3">
      <h2 className="text-[13px] font-bold uppercase tracking-wide text-[var(--muted)] whitespace-nowrap">{title}</h2>
      <span className="text-[12px] font-semibold text-[var(--muted)] bg-[var(--surface-2)] border border-[var(--border)] rounded-full px-1.5 min-w-[20px] text-center">{count}</span>
    </div>
  );
}

function ReminderCard({ r, onCancel, onDone, onSnooze, onOpen, muted }) {
  const f = formatRemind(r.remind_at);
  const done = r.status !== "pending";
  const label =
    r.status === "cancelled" ? "Отменено"
    : r.status === "done" ? "Выполнено · " + f.text
    : r.status === "sent" ? "Отправлено · " + f.text
    : f.text;
  const icon = r.status === "cancelled" ? "close" : done ? "check" : "bell";
  return (
    <div className={`reminder-card card-in rounded-2xl border border-[var(--border)] bg-[var(--surface)] p-3.5 sm:p-4 ${done ? "opacity-70" : ""}`}>
      <div className="flex items-center gap-3">
        <div className={`grid place-items-center w-10 h-10 rounded-xl shrink-0 reminder-icon-${done ? "done" : f.tone}`}>
          <Icon name={icon} size={18} />
        </div>
        <div className="min-w-0 flex-1">
          <p className={`text-[15px] font-medium text-[var(--text)] truncate ${r.status === "cancelled" ? "line-through opacity-70" : ""}`}>{r.text}</p>
          <div className="flex items-center gap-2 mt-0.5">
            <span className={`text-[12px] font-semibold reminder-tone-${done ? "done" : f.tone}`}>{label}</span>
            <button onClick={() => onOpen(r)} className="text-[12px] text-[var(--muted)] hover:text-[var(--accent)] transition inline-flex items-center gap-0.5">
              к записи <Icon name="chevron" size={12} />
            </button>
          </div>
        </div>
      </div>

      {r.status === "pending" && (
        <div className="flex flex-wrap items-center gap-1.5 mt-3 pl-[52px]">
          <button onClick={() => onDone && onDone(r)} className="inline-flex items-center gap-1 text-[12px] font-semibold str-text-green px-2.5 py-1.5 rounded-lg border border-[var(--border)] hover:bg-[var(--surface-2)] transition">
            <Icon name="check" size={14} /> Готово
          </button>
          <button onClick={() => onSnooze && onSnooze(r, 1)} className="inline-flex items-center gap-1 text-[12px] font-semibold text-[var(--accent)] px-2.5 py-1.5 rounded-lg border border-[var(--border)] hover:bg-[var(--surface-2)] transition">
            <Icon name="bell" size={13} /> +1 день
          </button>
          <button onClick={() => onSnooze && onSnooze(r, 7)} className="inline-flex items-center gap-1 text-[12px] font-semibold text-[var(--accent)] px-2.5 py-1.5 rounded-lg border border-[var(--border)] hover:bg-[var(--surface-2)] transition">
            +7 дней
          </button>
          <button onClick={() => onCancel(r)} className="inline-flex items-center gap-1 text-[12px] font-semibold text-[var(--muted)] hover:text-[var(--danger)] px-2.5 py-1.5 rounded-lg border border-[var(--border)] hover:bg-[var(--surface-2)] transition">
            Отменить
          </button>
        </div>
      )}
    </div>
  );
}

function LoginScreen({ onLogin }) {
  const [config, setConfig] = React.useState(null);
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState("");
  const [mode, setMode] = React.useState("tg"); // tg | login
  const [uname, setUname] = React.useState("");
  const [pwd, setPwd] = React.useState("");
  const widgetRef = React.useRef(null);

  React.useEffect(() => {
    api.getConfig().then(setConfig).catch(() => setConfig({ bot_username: null }));
  }, []);

  React.useEffect(() => {
    window.onTelegramAuth = async (user) => {
      setError(""); setBusy(true);
      try {
        await api.authTelegram(user);
        onLogin();
      } catch (e) {
        setError(e && e.status === 403 ? "У этого аккаунта нет доступа." : "Не удалось войти. Попробуй ещё раз.");
        setBusy(false);
      }
    };
    return () => { delete window.onTelegramAuth; };
  }, [onLogin]);

  React.useEffect(() => {
    if (!config || !config.bot_username || !widgetRef.current) return;
    widgetRef.current.innerHTML = "";
    const s = document.createElement("script");
    s.async = true;
    s.src = "https://telegram.org/js/telegram-widget.js?22";
    s.setAttribute("data-telegram-login", config.bot_username);
    s.setAttribute("data-size", "large");
    s.setAttribute("data-radius", "12");
    s.setAttribute("data-onauth", "onTelegramAuth(user)");
    s.setAttribute("data-request-access", "write");
    widgetRef.current.appendChild(s);
  }, [config]);

  const demo = async () => {
    setBusy(true);
    try { await api.authTelegram({ demo: true }); onLogin(); }
    catch (e) { setError("Демо-вход недоступен."); setBusy(false); }
  };

  const doLogin = async () => {
    if (!uname.trim() || !pwd) return;
    setError(""); setBusy(true);
    try {
      await api.login({ username: uname.trim(), password: pwd });
      onLogin();
    } catch (e) {
      setError(e && e.status === 401 ? "Неверный логин или пароль." : "Не удалось войти.");
      setBusy(false);
    }
  };

  return (
    <div className="min-h-screen grid place-items-center px-6 bg-[var(--bg)]">
      <div className="w-full max-w-sm text-center">
        <img src="logo.png" alt="Умный блокнот" className="mx-auto mb-6 w-20 h-20 rounded-3xl shadow-[0_10px_30px_-10px_var(--accent)]" />
        <h1 className="text-2xl font-extrabold tracking-tight text-[var(--text)]">Умный блокнот</h1>
        <p className="mt-2 text-[15px] leading-relaxed text-[var(--muted)]">
          Скидывай мысли, задачи и заметки — ИИ сам разложит их по категориям, поставит теги и напомнит вовремя.
        </p>

        {mode === "tg" ? (
          <>
            <div className="mt-7 flex flex-col items-center gap-3 min-h-[52px]">
              {busy && <Spinner size={24} />}
              {!busy && config && config.bot_username && <div ref={widgetRef} />}
              {!busy && config && !config.bot_username && (
                <button onClick={demo}
                  className="w-full h-12 rounded-2xl bg-[#229ED9] hover:bg-[#1b8dc4] text-white font-bold text-[15px] inline-flex items-center justify-center gap-2.5 transition active:scale-[.99]">
                  <Icon name="telegram" size={20} strokeWidth={1.8} /> Войти (демо)
                </button>
              )}
              {!config && <Spinner size={24} />}
            </div>
            <button onClick={() => { setError(""); setMode("login"); }} className="mt-5 text-[13px] font-semibold text-[var(--accent)] hover:underline">
              Войти по логину и паролю
            </button>
          </>
        ) : (
          <div className="mt-7 space-y-2.5 text-left">
            <input value={uname} onChange={(e) => setUname(e.target.value)} placeholder="логин" autoCapitalize="none"
              className="w-full rounded-xl border border-[var(--border)] bg-[var(--surface-2)] px-3.5 h-12 text-[15px] text-[var(--text)] outline-none focus:border-[var(--accent)] transition" />
            <input type="password" value={pwd} onChange={(e) => setPwd(e.target.value)} onKeyDown={(e) => e.key === "Enter" && doLogin()} placeholder="пароль"
              className="w-full rounded-xl border border-[var(--border)] bg-[var(--surface-2)] px-3.5 h-12 text-[15px] text-[var(--text)] outline-none focus:border-[var(--accent)] transition" />
            <Button variant="primary" className="w-full h-12" onClick={doLogin} disabled={busy || !uname.trim() || !pwd}>
              {busy ? <Spinner /> : <Icon name="arrowRight" size={17} />} Войти
            </Button>
            <button onClick={() => { setError(""); setMode("tg"); }} className="w-full text-center pt-1 text-[13px] font-semibold text-[var(--accent)] hover:underline">
              ← Войти через Telegram
            </button>
          </div>
        )}

        {error && <p className="mt-4 text-[13px] str-text-red font-semibold">{error}</p>}
        <p className="mt-4 text-[12px] text-[var(--muted)]">Логин/пароль задаётся в настройках после входа через Telegram.</p>
      </div>
    </div>
  );
}

function ScreenHead({ title, sub, children }) {
  return (
    <div className="flex items-start gap-3 mb-5">
      <div className="min-w-0">
        <h1 className="text-[22px] sm:text-[26px] font-extrabold tracking-tight text-[var(--text)]">{title}</h1>
        {sub && <p className="mt-1 text-[13px] sm:text-sm text-[var(--muted)]" style={{ textWrap: "pretty" }}>{sub}</p>}
      </div>
      {children && <div className="ml-auto shrink-0 pt-1">{children}</div>}
    </div>
  );
}

Object.assign(window, { NotesScreen, SearchScreen, RemindersScreen, LoginScreen, EmptyState, ScreenHead, ReminderCard });
