import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { getAuthToken, clearAuthToken } from "@/lib/auth/client";
import { SiteShell } from "@/components/site-shell";
import {
  isAdmin,
  claimAdmin,
  adminListGames,
  adminListCategories,
  adminUpdateGame,
  adminDeleteGame,
  adminUpdateCategory,
} from "@/lib/admin.functions";
import {
  adminGetSites,
  adminCreateSiteClone,
  adminGetStats,
  adminGetTranslateSettings,
  adminSetTranslateSettings,
  adminTranslateAllGames,
} from "@/lib/sites.functions";
import { syncGamesFromFeed } from "@/lib/games.functions";

export const Route = createFileRoute("/admin")({
  component: AdminPage,
});

function AdminPage() {
  const navigate = useNavigate();
  const [ready, setReady] = useState(false);

  useEffect(() => {
    const token = getAuthToken();
    setReady(true);
    if (!token) navigate({ to: "/auth" });
  }, [navigate]);

  if (!ready) return <SiteShell><div className="py-20 text-center text-text-dim">...</div></SiteShell>;
  if (!getAuthToken()) return null;

  return <AdminContent />;
}

function AdminContent() {
  const qc = useQueryClient();
  const checkAdmin = useServerFn(isAdmin);
  const doClaim = useServerFn(claimAdmin);
  const doSync = useServerFn(syncGamesFromFeed);
  const fetchGames = useServerFn(adminListGames);
  const fetchCats = useServerFn(adminListCategories);
  const doUpdateGame = useServerFn(adminUpdateGame);
  const doDeleteGame = useServerFn(adminDeleteGame);
  const doUpdateCat = useServerFn(adminUpdateCategory);

  const { data: adminCheck, isLoading: checking } = useQuery({
    queryKey: ["isAdmin"],
    queryFn: () => checkAdmin(),
  });

  const claim = useMutation({
    mutationFn: () => doClaim(),
    onSuccess: () => qc.invalidateQueries({ queryKey: ["isAdmin"] }),
  });

  if (checking) return <SiteShell><div className="py-20 text-center text-text-dim">Проверка прав...</div></SiteShell>;

  if (!adminCheck?.admin) {
    return (
      <SiteShell>
        <div className="max-w-md mx-auto bg-surface border border-white/5 rounded-2xl p-8 text-center">
          <h1 className="text-2xl font-display text-white mb-4">Нет прав администратора</h1>
          <p className="text-text-dim text-sm mb-6">
            Если вы первый пользователь и админ ещё не назначен, можете забрать роль себе.
          </p>
          <button
            type="button"
            onClick={() => claim.mutate()}
            disabled={claim.isPending}
            className="px-6 py-3 bg-accent text-white rounded-lg font-bold uppercase tracking-wider disabled:opacity-50"
          >
            {claim.isPending ? "..." : "Стать админом"}
          </button>
          {claim.error && <p className="mt-4 text-sm text-red-400">{(claim.error as Error).message}</p>}
        </div>
      </SiteShell>
    );
  }

  return <AdminDashboard
    fetchGames={fetchGames}
    fetchCats={fetchCats}
    doSync={doSync}
    doUpdateGame={doUpdateGame}
    doDeleteGame={doDeleteGame}
    doUpdateCat={doUpdateCat}
  />;
}

function setPreviewSite(slug: string) {
  document.cookie = `site_slug=${encodeURIComponent(slug)};path=/;max-age=31536000`;
  window.location.href = "/";
}

function AdminDashboard({ fetchGames, fetchCats, doSync, doUpdateGame, doDeleteGame, doUpdateCat }: any) {
  const qc = useQueryClient();
  const fetchSites = useServerFn(adminGetSites);
  const fetchStats = useServerFn(adminGetStats);
  const createClone = useServerFn(adminCreateSiteClone);
  const getTranslate = useServerFn(adminGetTranslateSettings);
  const setTranslate = useServerFn(adminSetTranslateSettings);
  const translateAll = useServerFn(adminTranslateAllGames);

  const [tab, setTab] = useState<"import" | "sites" | "games" | "cats">("import");
  const [cloneSlug, setCloneSlug] = useState("");
  const [cloneName, setCloneName] = useState("");
  const [gamesPage, setGamesPage] = useState(0);
  const gamesPageSize = 100;

  const { data: stats } = useQuery({ queryKey: ["admin", "stats"], queryFn: () => fetchStats() });
  const { data: sites = [] } = useQuery({ queryKey: ["admin", "sites"], queryFn: () => fetchSites() });
  const { data: translateSettings } = useQuery({
    queryKey: ["admin", "translate"],
    queryFn: () => getTranslate(),
  });

  const { data: gamesData, isLoading: loadingGames } = useQuery({
    queryKey: ["admin", "games", gamesPage],
    queryFn: () => fetchGames({ data: { limit: gamesPageSize, offset: gamesPage * gamesPageSize } }),
    enabled: tab === "games",
  });
  const games = gamesData?.items ?? [];
  const gamesTotal = gamesData?.total ?? 0;
  const { data: categories = [] } = useQuery({
    queryKey: ["admin", "categories"],
    queryFn: () => fetchCats(),
    enabled: tab === "cats" || tab === "games",
  });

  const sync = useMutation({
    mutationFn: () => doSync({ data: {} }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["admin"] });
      qc.invalidateQueries({ queryKey: ["games"] });
      qc.invalidateQueries({ queryKey: ["site-config"] });
    },
  });

  const translateBatch = useMutation({
    mutationFn: () => translateAll({ data: { limit: 20000 } }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["admin"] });
      qc.invalidateQueries({ queryKey: ["games"] });
    },
  });

  const clone = useMutation({
    mutationFn: () => createClone({ data: { slug: cloneSlug, name: cloneName } }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["admin", "sites"] });
      setCloneSlug("");
      setCloneName("");
    },
  });

  const saveTranslate = useMutation({
    mutationFn: (auto: boolean) => setTranslate({ data: { autoTranslate: auto, lang: "ru" } }),
    onSuccess: () => qc.invalidateQueries({ queryKey: ["admin", "translate"] }),
  });

  async function signOut() {
    clearAuthToken();
    window.location.href = "/";
  }

  return (
    <SiteShell>
      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-8">
        <div>
          <h1 className="text-3xl font-display text-white">Админка</h1>
          {stats && (
            <p className="text-sm text-text-dim mt-1">
              {stats.games} игр в базе · {stats.sites} сайтов · текущий: {stats.currentSite}
            </p>
          )}
        </div>
        <button onClick={signOut} className="px-5 py-2 bg-surface border border-white/10 text-xs uppercase tracking-wider rounded-lg">
          Выйти
        </button>
      </div>

      <div className="flex gap-2 flex-wrap mb-8">
        {(["import", "sites", "games", "cats"] as const).map((t) => (
          <button
            key={t}
            type="button"
            onClick={() => setTab(t)}
            className={`px-4 py-2 rounded-xl text-xs font-bold uppercase tracking-wider border ${
              tab === t ? "bg-accent text-white border-accent" : "bg-surface border-white/10"
            }`}
          >
            {t === "import" ? "Импорт" : t === "sites" ? "Сайты" : t === "games" ? "Игры" : "Категории"}
          </button>
        ))}
      </div>

      {tab === "import" && (
        <section className="space-y-6 mb-12">
          <div className="bg-surface border border-white/8 rounded-2xl p-6">
            <h2 className="text-xl font-display text-white mb-2">Массовый импорт</h2>
            <p className="text-sm text-text-dim mb-4">
              7 источников GameMonetize (категории + Unity + RSS). GamePix отключён — в РФ не открывается.
            </p>
            <ul className="text-xs text-text-muted mb-4 space-y-1 list-disc pl-5">
              <li>GameMonetize (основной, аркады, казуальные, гонки, приключения, Unity)</li>
              <li>GamePix (дополнительно, если API отвечает)</li>
            </ul>
            <div className="flex flex-wrap gap-3 mb-4">
              <button
                onClick={() => sync.mutate()}
                disabled={sync.isPending}
                className="px-5 py-2 bg-accent text-white font-bold uppercase text-xs rounded-lg disabled:opacity-50"
              >
                {sync.isPending ? "Импорт..." : "Импорт всех игр"}
              </button>
              <button
                onClick={() => translateBatch.mutate()}
                disabled={translateBatch.isPending}
                className="px-5 py-2 bg-neon text-bg font-bold uppercase text-xs rounded-lg disabled:opacity-50"
              >
                {translateBatch.isPending ? "Перевод..." : "Перевести все игры (RU)"}
              </button>
            </div>
            <label className="flex items-center gap-2 text-sm text-text-dim">
              <input
                type="checkbox"
                checked={translateSettings?.autoTranslate ?? true}
                onChange={(e) => saveTranslate.mutate(e.target.checked)}
              />
              Автоперевод при ручном редактировании (Google Translate + словарь)
            </label>
            {sync.data && (
              <div className="mt-4 p-4 bg-neon/10 border border-neon/30 rounded-lg text-sm text-neon">
                Добавлено: {sync.data.inserted}, пропущено (дубли): {sync.data.skipped ?? 0}, обработано: {sync.data.total}
                <br />
                В базе: {sync.data.totalInDb} игр
                {sync.data.bySource && (
                  <pre className="mt-2 text-xs text-text-dim overflow-auto">{JSON.stringify(sync.data.bySource, null, 2)}</pre>
                )}
              </div>
            )}
            {translateBatch.data && (
              <div className="mt-4 p-4 bg-accent/10 border border-accent/30 rounded-lg text-sm text-accent">
                Переведено записей: {translateBatch.data.translated} из {translateBatch.data.total}
              </div>
            )}
            {sync.error && (
              <div className="mt-4 p-4 bg-red-500/10 border border-red-500/30 rounded-lg text-sm text-red-400">
                {(sync.error as Error).message}
              </div>
            )}
          </div>
        </section>
      )}

      {tab === "sites" && (
        <section className="space-y-6 mb-12">
          <div className="bg-surface border border-white/8 rounded-2xl p-6">
            <h2 className="text-xl font-display text-white mb-4">Клоны сайта ({sites.length})</h2>
            <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-4 mb-6">
              {sites.map((s: any) => (
                <div key={s.id} className="border border-white/10 rounded-xl p-4">
                  <p className="font-bold text-white">{s.name}</p>
                  <p className="text-xs text-text-dim font-mono">/{s.slug}</p>
                  <p className="text-xs text-text-muted mt-1">{s.gameCount} игр</p>
                  <button
                    type="button"
                    onClick={() => setPreviewSite(s.slug)}
                    className="mt-3 text-xs text-accent hover:text-neon"
                  >
                    Открыть превью →
                  </button>
                </div>
              ))}
            </div>
            <h3 className="text-sm font-bold uppercase tracking-widest text-text-muted mb-3">Создать клон</h3>
            <div className="grid sm:grid-cols-2 gap-3 mb-3">
              <input
                value={cloneSlug}
                onChange={(e) => setCloneSlug(e.target.value)}
                placeholder="slug (латиница, напр. orbit-zone)"
                className="bg-bg border border-white/10 rounded-lg px-3 py-2 text-sm"
              />
              <input
                value={cloneName}
                onChange={(e) => setCloneName(e.target.value)}
                placeholder="Название сайта"
                className="bg-bg border border-white/10 rounded-lg px-3 py-2 text-sm"
              />
            </div>
            <button
              type="button"
              onClick={() => clone.mutate()}
              disabled={clone.isPending || !cloneSlug || !cloneName}
              className="px-5 py-2 bg-accent text-white text-xs font-bold uppercase rounded-lg disabled:opacity-50"
            >
              {clone.isPending ? "Создание..." : "Создать клон с уникальными текстами и ЧПУ"}
            </button>
            {clone.error && <p className="mt-2 text-sm text-red-400">{(clone.error as Error).message}</p>}
          </div>
        </section>
      )}

      {tab === "cats" && (
        <section className="mb-12">
        <h2 className="text-xl font-display text-white mb-4">Категории ({categories.length})</h2>
        <div className="bg-surface border border-white/5 rounded-2xl overflow-hidden">
          <table className="w-full text-sm">
            <thead className="text-left text-[10px] uppercase tracking-widest text-text-muted border-b border-white/5">
              <tr><th className="p-3">Название</th><th className="p-3">Slug (ЧПУ)</th><th className="p-3 w-24">Порядок</th><th className="p-3 w-24"></th></tr>
            </thead>
            <tbody>
              {categories.map((c: any) => (
                <CategoryRow key={c.id} cat={c} onSave={doUpdateCat} onSaved={() => {
                  qc.invalidateQueries({ queryKey: ["admin", "categories"] });
                  qc.invalidateQueries({ queryKey: ["categories"] });
                }} />
              ))}
            </tbody>
          </table>
        </div>
        </section>
      )}

      {tab === "games" && (
      <section>
        <div className="flex flex-wrap items-center justify-between gap-4 mb-4">
          <h2 className="text-xl font-display text-white">Игры ({gamesTotal})</h2>
          {gamesTotal > gamesPageSize && (
            <div className="flex items-center gap-2 text-xs">
              <button
                type="button"
                disabled={gamesPage === 0}
                onClick={() => setGamesPage((p) => Math.max(0, p - 1))}
                className="px-3 py-1 bg-surface border border-white/10 rounded disabled:opacity-40"
              >
                ←
              </button>
              <span className="text-text-dim">
                {gamesPage * gamesPageSize + 1}–{Math.min((gamesPage + 1) * gamesPageSize, gamesTotal)} из {gamesTotal}
              </span>
              <button
                type="button"
                disabled={(gamesPage + 1) * gamesPageSize >= gamesTotal}
                onClick={() => setGamesPage((p) => p + 1)}
                className="px-3 py-1 bg-surface border border-white/10 rounded disabled:opacity-40"
              >
                →
              </button>
            </div>
          )}
        </div>
        {loadingGames ? (
          <div className="py-20 text-center text-text-dim">Загрузка...</div>
        ) : games.length === 0 ? (
          <div className="bg-surface border border-white/5 rounded-2xl p-12 text-center text-text-dim">
            Каталог пуст. Нажмите «Импорт 40 игр» вверху.
          </div>
        ) : (
          <div className="bg-surface border border-white/5 rounded-2xl overflow-hidden overflow-x-auto">
            <table className="w-full text-sm min-w-[800px]">
              <thead className="text-left text-[10px] uppercase tracking-widest text-text-muted border-b border-white/5">
                <tr>
                  <th className="p-3">Название</th>
                  <th className="p-3">Slug (ЧПУ)</th>
                  <th className="p-3 w-40">Категория</th>
                  <th className="p-3 w-20">Hot</th>
                  <th className="p-3 w-32"></th>
                </tr>
              </thead>
              <tbody>
                {games.map((g: any) => (
                  <GameRow
                    key={g.id}
                    game={g}
                    categories={categories}
                    onSave={doUpdateGame}
                    onDelete={doDeleteGame}
                    onChanged={() => {
                      qc.invalidateQueries({ queryKey: ["admin", "games"] });
                      qc.invalidateQueries({ queryKey: ["games", "home"] });
                    }}
                  />
                ))}
              </tbody>
            </table>
          </div>
        )}
      </section>
      )}
    </SiteShell>
  );
}

function CategoryRow({ cat, onSave, onSaved }: any) {
  const [slug, setSlug] = useState(cat.slug);
  const [name, setName] = useState(cat.name);
  const [sortOrder, setSortOrder] = useState(cat.sort_order);
  const [saving, setSaving] = useState(false);
  const dirty = slug !== cat.slug || name !== cat.name || sortOrder !== cat.sort_order;

  async function save() {
    setSaving(true);
    try {
      await onSave({ data: { id: cat.id, slug, name, sort_order: Number(sortOrder) } });
      onSaved();
    } catch (e: any) { alert(e.message); }
    finally { setSaving(false); }
  }
  return (
    <tr className="border-b border-white/5">
      <td className="p-3"><input value={name} onChange={(e) => setName(e.target.value)} className="bg-bg border border-white/10 rounded px-2 py-1 w-full" /></td>
      <td className="p-3"><input value={slug} onChange={(e) => setSlug(e.target.value)} className="bg-bg border border-white/10 rounded px-2 py-1 w-full font-mono text-xs" /></td>
      <td className="p-3"><input type="number" value={sortOrder} onChange={(e) => setSortOrder(Number(e.target.value))} className="bg-bg border border-white/10 rounded px-2 py-1 w-full" /></td>
      <td className="p-3">
        {dirty && (
          <button onClick={save} disabled={saving} className="px-3 py-1 bg-accent text-white rounded text-xs uppercase disabled:opacity-50">
            {saving ? "..." : "Сохранить"}
          </button>
        )}
      </td>
    </tr>
  );
}

function GameRow({ game, categories, onSave, onDelete, onChanged }: any) {
  const [slug, setSlug] = useState(game.slug);
  const [title, setTitle] = useState(game.title);
  const [categoryId, setCategoryId] = useState<string | null>(game.category_id);
  const [featured, setFeatured] = useState(game.is_featured);
  const [saving, setSaving] = useState(false);
  const dirty = slug !== game.slug || title !== game.title || categoryId !== game.category_id || featured !== game.is_featured;

  async function save() {
    setSaving(true);
    try {
      await onSave({ data: { id: game.id, slug, title, category_id: categoryId, is_featured: featured } });
      onChanged();
    } catch (e: any) { alert(e.message); }
    finally { setSaving(false); }
  }
  async function remove() {
    if (!confirm(`Удалить «${game.title}»?`)) return;
    await onDelete({ data: { id: game.id } });
    onChanged();
  }
  return (
    <tr className="border-b border-white/5">
      <td className="p-3"><input value={title} onChange={(e) => setTitle(e.target.value)} className="bg-bg border border-white/10 rounded px-2 py-1 w-full" /></td>
      <td className="p-3"><input value={slug} onChange={(e) => setSlug(e.target.value)} className="bg-bg border border-white/10 rounded px-2 py-1 w-full font-mono text-xs" /></td>
      <td className="p-3">
        <select value={categoryId ?? ""} onChange={(e) => setCategoryId(e.target.value || null)} className="bg-bg border border-white/10 rounded px-2 py-1 w-full">
          <option value="">—</option>
          {categories.map((c: any) => <option key={c.id} value={c.id}>{c.name}</option>)}
        </select>
      </td>
      <td className="p-3 text-center">
        <input type="checkbox" checked={featured} onChange={(e) => setFeatured(e.target.checked)} className="w-5 h-5 accent-accent" />
      </td>
      <td className="p-3 flex gap-2">
        {dirty && (
          <button onClick={save} disabled={saving} className="px-3 py-1 bg-accent text-white rounded text-xs uppercase disabled:opacity-50">
            {saving ? "..." : "Сохр."}
          </button>
        )}
        <button onClick={remove} className="px-3 py-1 bg-red-500/20 text-red-400 rounded text-xs uppercase">
          Удалить
        </button>
      </td>
    </tr>
  );
}
