import { createServerFn } from "@tanstack/react-start";
import { z } from "zod";
import { getDb } from "@/lib/db";
import { requireAuth } from "@/lib/auth/middleware";
import { createSiteClone, getCurrentSite, listSites } from "@/lib/sites";
import { translateAllGamesInDb } from "@/lib/translate";

function assertAdmin(userId: string) {
  const db = getDb();
  const role = db
    .prepare("SELECT id FROM user_roles WHERE user_id = ? AND role = 'admin'")
    .get(userId);
  if (!role) throw new Error("Доступ только для администраторов");
}

export const adminGetSites = createServerFn({ method: "GET" })
  .middleware([requireAuth])
  .handler(async ({ context }) => {
    assertAdmin(context.userId);
    const db = getDb();
    const sites = listSites();
    const counts = db
      .prepare("SELECT site_id, COUNT(*) AS c FROM site_games GROUP BY site_id")
      .all() as { site_id: string; c: number }[];
    const countMap = new Map(counts.map((c) => [c.site_id, c.c]));
    return sites.map((s) => ({ ...s, gameCount: countMap.get(s.id) ?? 0 }));
  });

export const adminCreateSiteClone = createServerFn({ method: "POST" })
  .middleware([requireAuth])
  .inputValidator((d: { slug: string; name: string; tagline?: string }) =>
    z
      .object({
        slug: z
          .string()
          .min(2)
          .max(40)
          .regex(/^[a-z0-9-]+$/, "Только латиница, цифры, дефис"),
        name: z.string().min(2).max(80),
        tagline: z.string().max(160).optional(),
      })
      .parse(d))
  .handler(async ({ data, context }) => {
    assertAdmin(context.userId);
    return createSiteClone(data);
  });

export const adminSetTranslateSettings = createServerFn({ method: "POST" })
  .middleware([requireAuth])
  .inputValidator((d: { autoTranslate: boolean; lang?: string }) =>
    z
      .object({
        autoTranslate: z.boolean(),
        lang: z.string().min(2).max(5).optional(),
      })
      .parse(d))
  .handler(async ({ data, context }) => {
    assertAdmin(context.userId);
    const db = getDb();
    db.prepare("INSERT OR REPLACE INTO app_settings (key, value) VALUES ('auto_translate', ?)").run(
      data.autoTranslate ? "1" : "0",
    );
    if (data.lang) {
      db.prepare("INSERT OR REPLACE INTO app_settings (key, value) VALUES ('translate_lang', ?)").run(
        data.lang,
      );
    }
    return { ok: true };
  });

export const adminGetTranslateSettings = createServerFn({ method: "GET" })
  .middleware([requireAuth])
  .handler(async ({ context }) => {
    assertAdmin(context.userId);
    const db = getDb();
    const auto = db.prepare("SELECT value FROM app_settings WHERE key = 'auto_translate'").get() as
      | { value: string }
      | undefined;
    const lang = db.prepare("SELECT value FROM app_settings WHERE key = 'translate_lang'").get() as
      | { value: string }
      | undefined;
    return {
      autoTranslate: auto?.value !== "0",
      lang: lang?.value || "ru",
    };
  });

export const adminTranslateAllGames = createServerFn({ method: "POST" })
  .middleware([requireAuth])
  .inputValidator((d: { limit?: number } | undefined) =>
    z.object({ limit: z.number().int().min(1).max(10_000).optional() }).parse(d ?? {}))
  .handler(async ({ data, context }) => {
    assertAdmin(context.userId);
    return translateAllGamesInDb({ limit: data.limit ?? 6000 });
  });

export const adminGetStats = createServerFn({ method: "GET" })
  .middleware([requireAuth])
  .handler(async ({ context }) => {
    assertAdmin(context.userId);
    const db = getDb();
    const games = db.prepare("SELECT COUNT(*) AS c FROM games").get() as { c: number };
    const siteGames = db.prepare("SELECT COUNT(*) AS c FROM site_games").get() as { c: number };
    const sites = db.prepare("SELECT COUNT(*) AS c FROM sites").get() as { c: number };
    const current = getCurrentSite();
    return { games: games.c, siteGames: siteGames.c, sites: sites.c, currentSite: current.slug };
  });
