/**
 * Server-side content reads from the FlatRender V2 API gateway.
 *
 * Replaces the legacy admin-api (:5000) integration: categories, templates
 * ("containers") and projects now come from the V2 content service via the
 * gateway at `/v1/*`. All V2 payloads are snake_case — this module maps them
 * into the camelCase `AdminCategory` / `AdminProject` shapes the UI already
 * consumes, so call sites are unchanged.
 *
 * Every function returns hardcoded fallback data (empty arrays / null) when the
 * gateway is unset or unreachable, so the app still works standalone.
 */

import { gatewayUrl } from "@/lib/api/gateway";

export interface AdminCategory {
  id: string;
  name: string;
  slug: string;
  description?: string;
  iconUrl?: string;
  type: "video" | "image" | "both";
  sortOrder: number;
  projectCount: number;
}

export interface AdminProject {
  id: string;
  title: string;
  slug: string;
  description?: string;
  type: "video" | "image";
  status: string;
  categoryId?: string;
  categoryName?: string;
  coverImageUrl?: string;
  previewVideoUrl?: string;
  tags: string[];
  metaJson?: string;
  sortOrder: number;
  mediaCount: number;
  createdAt: string;
  updatedAt: string;
}

export interface AdminProjectsResponse {
  total: number;
  page: number;
  pageSize: number;
  items: AdminProject[];
}

// ── V2 content-service response shapes (snake_case JSON) ──────────────────────

interface V2Category {
  id: string;
  parent_id?: string | null;
  name: string;
  slug: string;
  description?: string | null;
  image_url?: string | null;
  icon?: string | null;
  is_active: boolean;
  sort: number;
  children: V2Category[];
}

interface V2ContainerSummary {
  id: string;
  slug: string;
  name: string;
  description?: string | null;
  image?: string | null;
  demo?: string | null;
  mini_demo?: string | null;
  is_published: boolean;
  is_premium: boolean;
  is_mockup: boolean;
  primary_mode: string;
  rate_avg?: number | null;
  rate_count: number;
  view_count: number;
  use_count: number;
  sort: number;
  sort_date: string;
  category_slugs: string[];
  tags: string[];
}

interface V2PagedContainers {
  items: V2ContainerSummary[];
  meta: { page: number; page_size: number; total: number; total_pages: number };
}

// ── Fetch helper ──────────────────────────────────────────────────────────────

async function safeGet<T>(path: string): Promise<T | null> {
  try {
    const res = await fetch(gatewayUrl(path), {
      next: { revalidate: 60 }, // ISR: cache public content for 60 s
      headers: { Accept: "application/json" },
    });
    if (!res.ok) return null;
    return (await res.json()) as T;
  } catch {
    return null;
  }
}

// ── Mappers (V2 → UI shapes) ──────────────────────────────────────────────────

/**
 * V2 containers are video templates — `primary_mode` is a render mode
 * (FIX / FLEXIBLE / MockUp / …), not a video/image type. There is no image
 * container concept, so every container maps to `type: "video"`.
 */
function containerToAdminProject(c: V2ContainerSummary): AdminProject {
  return {
    id: c.id,
    title: c.name,
    slug: c.slug,
    description: c.description ?? undefined,
    type: "video",
    status: c.is_published ? "published" : "draft",
    categoryId: undefined,
    categoryName: undefined,
    coverImageUrl: c.image ?? undefined,
    previewVideoUrl: c.demo ?? c.mini_demo ?? undefined,
    tags: c.tags ?? [],
    metaJson: undefined,
    sortOrder: c.sort,
    mediaCount: 0,
    createdAt: c.sort_date ?? "",
    updatedAt: c.sort_date ?? "",
  };
}

function categoryToAdmin(c: V2Category): AdminCategory {
  return {
    id: c.id,
    name: c.name,
    slug: c.slug,
    description: c.description ?? undefined,
    iconUrl: c.image_url ?? c.icon ?? undefined,
    type: "both",
    sortOrder: c.sort,
    projectCount: 0,
  };
}

/** Flatten the V2 category tree depth-first into a flat list. */
function flattenCategories(nodes: V2Category[]): AdminCategory[] {
  const out: AdminCategory[] = [];
  const walk = (list: V2Category[]) => {
    for (const n of list) {
      out.push(categoryToAdmin(n));
      if (n.children?.length) walk(n.children);
    }
  };
  walk(nodes);
  return out;
}

// ── Public API ────────────────────────────────────────────────────────────────

export async function fetchCategories(
  type?: "video" | "image"
): Promise<AdminCategory[]> {
  // V2 categories have no video/image type; `type` is accepted for API
  // compatibility but the content service returns a single tree.
  void type;
  const tree = await safeGet<V2Category[]>("/v1/categories");
  return tree ? flattenCategories(tree) : [];
}

export async function fetchProjects(opts?: {
  type?: "video" | "image";
  categorySlug?: string;
  search?: string;
  page?: number;
  pageSize?: number;
}): Promise<AdminProjectsResponse> {
  // V2 .NET query binding uses C# property names (camelCase), NOT the snake_case
  // used in response bodies. Send camelCase keys here.
  const params = new URLSearchParams();
  params.set("isPublished", "true");
  if (opts?.search) params.set("search", opts.search);
  if (opts?.page) params.set("page", String(opts.page));
  if (opts?.pageSize) params.set("pageSize", String(opts.pageSize));
  // Note: V2 has no video/image container type and filters categories by GUID
  // (not slug), so `opts.type` / `opts.categorySlug` are intentionally ignored.

  const qs = params.toString() ? `?${params}` : "";
  const paged = await safeGet<V2PagedContainers>(`/v1/templates${qs}`);
  if (!paged) return { total: 0, page: 1, pageSize: 20, items: [] };

  return {
    total: paged.meta.total,
    page: paged.meta.page,
    pageSize: paged.meta.page_size,
    items: (paged.items ?? []).map(containerToAdminProject),
  };
}

export async function fetchProject(slug: string): Promise<AdminProject | null> {
  const c = await safeGet<V2ContainerSummary>(
    `/v1/templates/${encodeURIComponent(slug)}`
  );
  return c ? containerToAdminProject(c) : null;
}

/** True when the gateway content endpoint is reachable. */
export async function isAdminApiAvailable(): Promise<boolean> {
  try {
    const res = await fetch(gatewayUrl("/v1/categories"), {
      next: { revalidate: 30 },
    });
    return res.ok;
  } catch {
    return false;
  }
}
