"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;

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

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

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

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

    return outerData as T;
}

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: {
                    "Content-Type":
                        "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);
}

/**
 * Loads every active translation for the requested sidebar module.
 *
 * The caller intentionally catches errors and uses the existing static
 * sidebar labels as fallback, so an API outage never breaks navigation.
 */
export async function getSidebarTranslations(
    moduleKey: SidebarTranslationModule,
): Promise<SidebarTranslation[]> {
    const first =
        await fetchTranslationPage(
            moduleKey,
            1,
        );

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

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

    for (
        let pageNumber = 2;
        pageNumber <= totalPages;
        pageNumber += 1
    ) {
        const next =
            await fetchTranslationPage(
                moduleKey,
                pageNumber,
            );

        items.push(
            ...(next.items ?? []),
        );
    }

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