"use client";

export type SidebarTranslationModule =
  | "pswg"
  | "ministry"
  | "cdc"
  | "cefp"
  | "cdcgpsf";

export type SidebarTranslation = {
  id: number;
  translationKey: string;
  englishText: string;
  khmerText: string;
  module: string | null;
  page: string | null;
  parentId?: number | null;
  isActive: boolean;
  createdAt?: string;
  updatedAt?: string;
};

type TranslationMeta = {
  page?: number;
  limit?: number;
  total?: number;
  totalPages?: number;
  hasNextPage?: boolean;
  hasPreviousPage?: boolean;
};

type TranslationListData = {
  items?: SidebarTranslation[];
  meta?: TranslationMeta;
};

type ApiEnvelope<T> = {
  success?: boolean;
  statusCode?: number;
  message?: string | string[];
  data: T;
};

type NestedApiEnvelope<T> = {
  success?: boolean;
  statusCode?: number;
  message?: string | string[];
  data: {
    success?: boolean;
    message?: string | string[];
    data: T;
  };
};

const API_BASE_URL =
  process.env.NEXT_PUBLIC_API_URL?.replace(/\/$/, "") ||
  "http://localhost:3001/api/v1";

const API_PAGE_SIZE = 100;

/* =========================================================
 * ACCESS TOKEN
 * ======================================================= */

function getAccessToken(): string | null {
  if (typeof window === "undefined") {
    return null;
  }

  return (
    window.localStorage.getItem("accessToken") ||
    window.localStorage.getItem("access_token") ||
    window.localStorage.getItem("token")
  );
}

/* =========================================================
 * NORMALIZE
 * ======================================================= */

function normalize(value: unknown): string {
  return String(value ?? "")
    .trim()
    .toLowerCase()
    .replace(/[_-]+/g, " ")
    .replace(/\s+/g, " ");
}

/* =========================================================
 * UNWRAP API
 * ======================================================= */

function unwrapData<T>(
  body:
    | ApiEnvelope<T>
    | NestedApiEnvelope<T>,
): T {
  const outerData = body?.data;

  if (
    outerData &&
    typeof outerData === "object" &&
    "data" in outerData
  ) {
    return (
      outerData as {
        data: T;
      }
    ).data;
  }

  return outerData as T;
}

/* =========================================================
 * MODULE ALIASES
 *
 * Backend may return:
 *
 * cdcgpsf
 * CDC G-PSF
 * CDC_GPSF
 * cdc-gpsf
 * ======================================================= */

function isSameModule(
  value: string | null | undefined,
  moduleKey: SidebarTranslationModule,
): boolean {
  const actual = normalize(value);

  const aliases: Record<
    SidebarTranslationModule,
    string[]
  > = {
    pswg: [
      "pswg",
      "private sector working group",
    ],

    ministry: [
      "ministry",
      "ministries",
    ],

    cdc: [
      "cdc",
    ],

    cefp: [
      "cefp",
    ],

    cdcgpsf: [
      "cdcgpsf",
      "cdc gpsf",
      "cdc g psf",
      "cdc-gpsf",
      "cdc_gpsf",
    ],
  };

  return (
    aliases[moduleKey]?.some(
      (alias) =>
        normalize(alias) === actual,
    ) ?? false
  );
}

/* =========================================================
 * FETCH ONE PAGE
 * ======================================================= */

async function fetchTranslationPage(
  moduleKey: SidebarTranslationModule,
  pageNumber: number,
): Promise<TranslationListData> {
  const query = new URLSearchParams({
    pageNumber: String(pageNumber),
    limit: String(API_PAGE_SIZE),
    module: moduleKey,
    isActive: "true",
  });

  const token = getAccessToken();

  const response = await fetch(
    `${API_BASE_URL}/translations?${query.toString()}`,
    {
      method: "GET",
      credentials: "include",
      cache: "no-store",
      headers: {
        Accept: "application/json",

        ...(token
          ? {
              Authorization: `Bearer ${token}`,
            }
          : {}),
      },
    },
  );

  if (!response.ok) {
    throw new Error(
      `Unable to load sidebar translations (${response.status})`,
    );
  }

  const body =
    (await response.json()) as
      | ApiEnvelope<TranslationListData>
      | NestedApiEnvelope<TranslationListData>;

  return unwrapData(body);
}

/* =========================================================
 * GET SIDEBAR TRANSLATIONS
 * ======================================================= */

export async function getSidebarTranslations(
  moduleKey: SidebarTranslationModule,
): Promise<SidebarTranslation[]> {
  /* -----------------------------------------------
   * FIRST PAGE
   * --------------------------------------------- */

  const first =
    await fetchTranslationPage(
      moduleKey,
      1,
    );

  const items: SidebarTranslation[] = [
    ...(first.items ?? []),
  ];

  /* -----------------------------------------------
   * TOTAL PAGES
   * --------------------------------------------- */

  const totalPages = Math.max(
    1,
    first.meta?.totalPages ?? 1,
  );

  /* -----------------------------------------------
   * LOAD OTHER PAGES
   * --------------------------------------------- */

  if (totalPages > 1) {
    const pages =
      await Promise.all(
        Array.from(
          {
            length:
              totalPages - 1,
          },
          (_, index) =>
            fetchTranslationPage(
              moduleKey,
              index + 2,
            ),
        ),
      );

    for (const page of pages) {
      items.push(
        ...(page.items ?? []),
      );
    }
  }


  return items.filter(
    (item) =>
      item.isActive !== false &&
      isSameModule(
        item.module,
        moduleKey,
      ),
  );
}