const API_BASE = (import.meta.env.VITE_API_BASE as string | undefined) ?? "";

function apiUrl(path: string): string {
  return API_BASE ? `${API_BASE}${path}` : path;
}

export type SiteConfig = {
  siteTitle: string;
  siteTitleEn: string;
  cwdApiBase: string;
  cwdSiteId?: string;
};

export type Post = {
  id: number;
  title: string;
  slug: string;
  excerpt: string;
  content: string;
  published: number;
  created_at: string;
  updated_at: string;
  view_count?: number;
};

export async function fetchConfig(): Promise<SiteConfig> {
  const r = await fetch(apiUrl("/api/config"));
  const j = (await r.json()) as {
    ok?: boolean;
    config?: SiteConfig;
  };
  if (!j.ok || !j.config) throw new Error("config");
  const viteId = import.meta.env.VITE_CWD_SITE_ID;
  if (viteId && !j.config.cwdSiteId) {
    j.config.cwdSiteId = viteId;
  }
  return j.config;
}

export async function fetchPosts(
  q?: string,
  opts?: { credentials?: RequestCredentials }
): Promise<Post[]> {
  const u = new URL(apiUrl("/api/posts"), window.location.origin);
  if (q) u.searchParams.set("q", q);
  const r = await fetch(u.toString(), {
    credentials: opts?.credentials ?? "same-origin"
  });
  const j = (await r.json()) as { ok?: boolean; posts?: Post[] };
  if (!r.ok || !j.ok) throw new Error("posts");
  return j.posts || [];
}

export async function fetchPost(
  idOrSlug: string,
  bump: boolean,
  opts?: { credentials?: RequestCredentials }
): Promise<Post> {
  const u = new URL(apiUrl(`/api/posts/${encodeURIComponent(idOrSlug)}`), window.location.origin);
  if (bump) u.searchParams.set("bump", "1");
  const r = await fetch(u.toString(), {
    credentials: opts?.credentials ?? "same-origin"
  });
  const j = (await r.json()) as { ok?: boolean; post?: Post; error?: string };
  if (!r.ok || !j.ok || !j.post) throw new Error(j.error || "post");
  return j.post;
}

export async function postJson<T>(
  path: string,
  body: unknown,
  opts?: { method?: string }
): Promise<T> {
  const r = await fetch(apiUrl(path), {
    method: opts?.method || "POST",
    headers: { "Content-Type": "application/json" },
    credentials: "include",
    body: JSON.stringify(body)
  });
  return (await r.json()) as T;
}

export async function adminLogin(token: string): Promise<boolean> {
  const j = await postJson<{ ok?: boolean }>("/api/admin/session", { token });
  return !!j.ok;
}

export async function savePost(
  data: Record<string, unknown>,
  id?: number | null
): Promise<Post> {
  if (id) {
    const r = await fetch(apiUrl(`/api/posts/${id}`), {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      credentials: "include",
      body: JSON.stringify(data)
    });
    const j = (await r.json()) as { ok?: boolean; post?: Post; error?: string };
    if (!r.ok || !j.ok || !j.post) throw new Error(j.error || "save");
    return j.post;
  }
  const { id: _omit, ...body } = data;
  void _omit;
  const r = await fetch(apiUrl("/api/posts"), {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    credentials: "include",
    body: JSON.stringify(body)
  });
  const j = (await r.json()) as { ok?: boolean; post?: Post; error?: string };
  if (!r.ok || !j.ok || !j.post) throw new Error(j.error || "save");
  return j.post;
}

export async function deletePostApi(id: number): Promise<void> {
  const r = await fetch(apiUrl(`/api/posts/${id}`), {
    method: "DELETE",
    credentials: "include"
  });
  const j = (await r.json()) as { ok?: boolean };
  if (!r.ok || !j.ok) throw new Error("delete");
}
