import { randomUUID } from "node:crypto";
import { getRequest } from "@tanstack/react-start/server";
import { getDb } from "@/lib/db";
import { uniquifyDescription, uniquifyMetaTitle, uniquifySlug, uniquifyTitle } from "./uniquify";

export type SiteConfig = {
  id: string;
  slug: string;
  name: string;
  tagline: string | null;
  meta_title: string | null;
  meta_description: string | null;
  logo_primary: string;
  logo_accent: string;
  theme: { accent?: string; neon?: string; bg?: string; surface?: string };
};

const DEFAULT_THEME = { accent: "#ea580c", neon: "#0284c7", bg: "#f4f6fa", surface: "#ffffff" };

export const LIGHT_THEME = DEFAULT_THEME;

export function resolveSiteSlug(): string {
  const fromEnv = process.env.SITE_SLUG;
  if (fromEnv) return fromEnv;

  try {
    const request = getRequest();
    const cookie = request?.headers?.get("cookie") ?? "";
    const match = cookie.match(/(?:^|;\s*)site_slug=([^;]+)/);
    if (match?.[1]) return decodeURIComponent(match[1]);
  } catch {
    // client bundle
  }
  return "main";
}

export function getSiteBySlug(slug: string): SiteConfig | null {
  const db = getDb();
  const row = db
    .prepare(
      `SELECT id, slug, name, tagline, meta_title, meta_description, logo_primary, logo_accent, theme_json
       FROM sites WHERE slug = ? AND is_active = 1`,
    )
    .get(slug) as Record<string, string> | undefined;
  if (!row) return null;
  let theme = DEFAULT_THEME;
  try {
    theme = { ...DEFAULT_THEME, ...JSON.parse(row.theme_json || "{}") };
  } catch {
    /* keep default */
  }
  return {
    id: row.id,
    slug: row.slug,
    name: row.name,
    tagline: row.tagline,
    meta_title: row.meta_title,
    meta_description: row.meta_description,
    logo_primary: row.logo_primary,
    logo_accent: row.logo_accent,
    theme,
  };
}

export function getCurrentSite(): SiteConfig {
  const site = getSiteBySlug(resolveSiteSlug()) ?? getSiteBySlug("main");
  if (site) return site;
  return {
    id: "default",
    slug: "main",
    name: "GameOrbit",
    tagline: "Тысячи HTML5 игр онлайн",
    meta_title: "GameOrbit — бесплатные онлайн игры",
    meta_description: null,
    logo_primary: "GAME",
    logo_accent: "ORBIT",
    theme: DEFAULT_THEME,
  };
}

export function listSites(): SiteConfig[] {
  const db = getDb();
  const rows = db
    .prepare(
      `SELECT id, slug, name, tagline, meta_title, meta_description, logo_primary, logo_accent, theme_json
       FROM sites WHERE is_active = 1 ORDER BY created_at ASC`,
    )
    .all() as Record<string, string>[];
  return rows.map((row) => {
    let theme = DEFAULT_THEME;
    try {
      theme = { ...DEFAULT_THEME, ...JSON.parse(row.theme_json || "{}") };
    } catch {
      /* keep default */
    }
    return {
      id: row.id,
      slug: row.slug,
      name: row.name,
      tagline: row.tagline,
      meta_title: row.meta_title,
      meta_description: row.meta_description,
      logo_primary: row.logo_primary,
      logo_accent: row.logo_accent,
      theme,
    };
  });
}

export function syncGameToAllSites(
  gameId: string,
  base: {
    slug: string;
    title: string;
    description: string | null;
    instructions: string | null;
    is_featured?: boolean;
  },
) {
  const db = getDb();
  const sites = db.prepare("SELECT id, slug, uniquify_seed, name FROM sites WHERE is_active = 1").all() as {
    id: string;
    slug: string;
    uniquify_seed: string;
    name: string;
  }[];

  const insert = db.prepare(
    `INSERT OR IGNORE INTO site_games (id, site_id, game_id, slug, title, description, instructions, meta_title, is_featured)
     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
  );

  for (const site of sites) {
    const title = site.slug === "main" ? base.title : uniquifyTitle(base.title, site.uniquify_seed);
    const description =
      site.slug === "main" ? base.description : uniquifyDescription(base.description, site.uniquify_seed);
    const slug = uniquifySlug(base.slug, site.slug, gameId);
    insert.run(
      randomUUID(),
      site.id,
      gameId,
      slug,
      title,
      description,
      base.instructions,
      uniquifyMetaTitle(title, site.name),
      base.is_featured ? 1 : 0,
    );
  }
}

export async function createSiteClone(input: {
  slug: string;
  name: string;
  tagline?: string;
  logoPrimary?: string;
  logoAccent?: string;
}) {
  const db = getDb();
  const exists = db.prepare("SELECT id FROM sites WHERE slug = ?").get(input.slug);
  if (exists) throw new Error("Сайт с таким slug уже существует");

  const siteId = randomUUID();
  const themes = [
    { accent: "#ea580c", neon: "#0284c7", bg: "#f4f6fa", surface: "#ffffff" },
    { accent: "#16a34a", neon: "#22c55e", bg: "#f4f6fa", surface: "#ffffff" },
    { accent: "#db2777", neon: "#ec4899", bg: "#f4f6fa", surface: "#ffffff" },
    { accent: "#7c3aed", neon: "#8b5cf6", bg: "#f4f6fa", surface: "#ffffff" },
    { accent: "#0284c7", neon: "#0ea5e9", bg: "#f4f6fa", surface: "#ffffff" },
    { accent: "#ca8a04", neon: "#eab308", bg: "#f4f6fa", surface: "#ffffff" },
  ];
  const siteCountRow = db.prepare("SELECT COUNT(*) AS c FROM sites").get() as { c: number };
  const theme = themes[siteCountRow.c % themes.length];

  db.prepare(
    `INSERT INTO sites (id, slug, name, tagline, meta_title, meta_description, logo_primary, logo_accent, uniquify_seed, theme_json)
     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
  ).run(
    siteId,
    input.slug,
    input.name,
    input.tagline ?? `Игры онлайн на ${input.name}`,
    `${input.name} — бесплатные онлайн игры`,
    `Каталог бесплатных HTML5 игр на ${input.name}. Играй без регистрации.`,
    input.logoPrimary ?? (input.name.split(" ")[0]?.toUpperCase().slice(0, 8) || "GAME"),
    input.logoAccent ?? (input.name.split(" ").slice(1).join(" ").toUpperCase().slice(0, 8) || "ZONE"),
    input.slug,
    JSON.stringify(theme),
  );

  const games = db
    .prepare("SELECT id, slug, title, description, instructions, is_featured FROM games")
    .all() as {
    id: string;
    slug: string;
    title: string;
    description: string | null;
    instructions: string | null;
    is_featured: number;
  }[];

  const insert = db.prepare(
    `INSERT OR IGNORE INTO site_games (id, site_id, game_id, slug, title, description, instructions, meta_title, is_featured)
     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
  );

  for (const g of games) {
    const title = uniquifyTitle(g.title, input.slug);
    const description = uniquifyDescription(g.description, input.slug);
    const slug = uniquifySlug(g.slug, input.slug, g.id);
    insert.run(
      randomUUID(),
      siteId,
      g.id,
      slug,
      title,
      description,
      g.instructions,
      uniquifyMetaTitle(title, input.name),
      g.is_featured,
    );
  }

  return { ok: true, siteId, slug: input.slug, games: games.length };
}
