/**
 * Commercial registry HTTP — Core Commercial APIs only.
 * Supports: ready | empty | unavailable | permission_denied | error
 * Never invents catalog rows.
 */

import { getValidAccessToken } from "@/lib/auth";
import type { AdapterResult, RegistryAvailability } from "../types";

const SERVER_API_BASE =
  process.env.NEXT_PUBLIC_API_BASE_URL ||
  process.env.NEXT_PUBLIC_BACKEND_URL ||
  "http://localhost:8000";
const API_BASE = typeof window === "undefined" ? SERVER_API_BASE : "/api/core";

async function authHeaders(): Promise<Headers> {
  const headers = new Headers({ "Content-Type": "application/json" });
  const token = await getValidAccessToken();
  if (token) headers.set("Authorization", `Bearer ${token}`);
  return headers;
}

function availabilityFromStatus(status: number): RegistryAvailability {
  if (status === 401 || status === 403) return "permission_denied";
  if (status === 404 || status === 501 || status === 502 || status === 503) {
    return "unavailable";
  }
  return "error";
}

export async function commercialGet<T>(
  path: string
): Promise<{ ok: true; data: T } | { ok: false; availability: RegistryAvailability; message: string; status: number }> {
  try {
    const res = await fetch(`${API_BASE}${path}`, { headers: await authHeaders() });
    if (!res.ok) {
      const body = await res.json().catch(() => ({}));
      return {
        ok: false,
        status: res.status,
        availability: availabilityFromStatus(res.status),
        message:
          (body as { error?: { message?: string } })?.error?.message ||
          res.statusText ||
          "درخواست ناموفق",
      };
    }
    return { ok: true, data: (await res.json()) as T };
  } catch (err) {
    return {
      ok: false,
      status: 0,
      availability: "unavailable",
      message: err instanceof Error ? err.message : "خطای شبکه",
    };
  }
}

export async function commercialPost<T>(
  path: string,
  body: unknown
): Promise<{ ok: true; data: T } | { ok: false; availability: RegistryAvailability; message: string; status: number }> {
  return commercialMutate<T>("POST", path, body);
}

export async function commercialPut<T>(
  path: string,
  body: unknown
): Promise<{ ok: true; data: T } | { ok: false; availability: RegistryAvailability; message: string; status: number }> {
  return commercialMutate<T>("PUT", path, body);
}

export async function commercialPatch<T>(
  path: string,
  body: unknown
): Promise<{ ok: true; data: T } | { ok: false; availability: RegistryAvailability; message: string; status: number }> {
  return commercialMutate<T>("PATCH", path, body);
}

export async function commercialDelete(
  path: string
): Promise<{ ok: true; data: null } | { ok: false; availability: RegistryAvailability; message: string; status: number }> {
  try {
    const res = await fetch(`${API_BASE}${path}`, {
      method: "DELETE",
      headers: await authHeaders(),
    });
    if (!res.ok) {
      const payload = await res.json().catch(() => ({}));
      return {
        ok: false,
        status: res.status,
        availability: availabilityFromStatus(res.status),
        message:
          (payload as { error?: { message?: string } })?.error?.message ||
          res.statusText ||
          "حذف ناموفق",
      };
    }
    return { ok: true, data: null };
  } catch (err) {
    return {
      ok: false,
      status: 0,
      availability: "unavailable",
      message: err instanceof Error ? err.message : "خطای شبکه",
    };
  }
}

async function commercialMutate<T>(
  method: "POST" | "PUT" | "PATCH",
  path: string,
  body: unknown
): Promise<{ ok: true; data: T } | { ok: false; availability: RegistryAvailability; message: string; status: number }> {
  try {
    const res = await fetch(`${API_BASE}${path}`, {
      method,
      headers: await authHeaders(),
      body: JSON.stringify(body),
    });
    if (!res.ok) {
      const payload = await res.json().catch(() => ({}));
      return {
        ok: false,
        status: res.status,
        availability: availabilityFromStatus(res.status),
        message:
          (payload as { error?: { message?: string } })?.error?.message ||
          res.statusText ||
          "درخواست ناموفق",
      };
    }
    if (res.status === 204) return { ok: true, data: {} as T };
    return { ok: true, data: (await res.json()) as T };
  } catch (err) {
    return {
      ok: false,
      status: 0,
      availability: "unavailable",
      message: err instanceof Error ? err.message : "خطای شبکه",
    };
  }
}

/** Extract items array from common commercial list envelopes. */
export function extractItems<T>(payload: unknown, keys: string[]): T[] {
  if (!payload || typeof payload !== "object") return [];
  const obj = payload as Record<string, unknown>;
  for (const key of keys) {
    const v = obj[key];
    if (Array.isArray(v)) return v as T[];
  }
  if (Array.isArray(payload)) return payload as T[];
  return [];
}

export function listResult<T>(
  items: T[],
  source: string,
  emptyMessage?: string
): AdapterResult<T[]> {
  return {
    availability: items.length ? "ready" : "empty",
    data: items,
    source,
    message: items.length ? undefined : emptyMessage,
  };
}

export function failResult<T>(
  availability: RegistryAvailability,
  message: string,
  empty: T
): AdapterResult<T> {
  return { availability, data: empty, message, source: "none" };
}
