import {
  meetingSummaryI18n,
  type MeetingSummaryText,
  type UiLang,
} from "./meeting-summary-i18n";

export type TranslationDictionary = Record<string, string>;
export type MeetingSummaryModule = "ministry" | "pswg" | "cdc" | "cefp" | "cdcgpsf";

export function meetingSummaryOwner(pathname: string): MeetingSummaryModule | null {
  const segment = pathname.split("/")[1];
  if (segment === "cdc-gpsf") return "cdcgpsf";
  return ["ministry", "pswg", "cdc", "cefp"].includes(segment)
    ? segment as MeetingSummaryModule
    : null;
}
export type MeetingSummaryTextOverride = {
  [K in keyof MeetingSummaryText]?: MeetingSummaryText[K] extends string
    ? string
    : Partial<MeetingSummaryText[K]>;
};

// Keep the existing `title` key for the sidebar / Admin page name.
// The list screen has its own heading, `page_title`.
export function meetingSummaryTranslationKey(path: string): string {
  if (path === "title") return "page_title";
  return path.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase();
}

// Only API-provided values may override another module's translations.
// Passing a fully resolved text object would also override them with fallbacks.
export function meetingSummaryOverrideFromDictionary(
  dictionary: TranslationDictionary,
): MeetingSummaryTextOverride {
  const result: Record<string, string | Record<string, string>> = {};
  for (const [key, fallback] of Object.entries(meetingSummaryI18n.en)) {
    if (typeof fallback === "string") {
      const value = dictionary[meetingSummaryTranslationKey(key)];
      if (typeof value === "string" && value.trim()) result[key] = value;
    } else {
      const group: Record<string, string> = {};
      for (const child of Object.keys(fallback)) {
        const value =
          dictionary[meetingSummaryTranslationKey(`${key}.${child}`)];
        if (typeof value === "string" && value.trim()) group[child] = value;
      }
      if (Object.keys(group).length) result[key] = group;
    }
  }
  return result as MeetingSummaryTextOverride;
}

export function resolveMeetingSummaryText(
  fallback: MeetingSummaryText,
  dictionary: TranslationDictionary = {},
  override?: MeetingSummaryTextOverride | null,
): MeetingSummaryText {
  function resolve(
    base: object,
    supplied: object | undefined,
    prefix = "",
  ): object {
    return Object.fromEntries(
      Object.entries(base).map(([key, value]) => {
        const path = prefix ? `${prefix}.${key}` : key;
        const replacement =
          supplied && Object.prototype.hasOwnProperty.call(supplied, key)
            ? (supplied as Record<string, unknown>)[key]
            : undefined;
        if (typeof value === "string") {
          const translated = dictionary[meetingSummaryTranslationKey(path)];
          return [
            key,
            typeof replacement === "string" && replacement.trim()
              ? replacement
              : typeof translated === "string" && translated.trim()
                ? translated
                : value,
          ];
        }
        return [
          key,
          resolve(
            value,
            replacement && typeof replacement === "object"
              ? replacement
              : undefined,
            path,
          ),
        ];
      }),
    );
  }
  return resolve(fallback, override ?? undefined) as MeetingSummaryText;
}

export function unwrapMeetingSummaryDictionary(
  payload: unknown,
): TranslationDictionary {
  let current = payload;
  for (let depth = 0; depth < 4; depth += 1) {
    if (!current || typeof current !== "object") break;
    const record = current as Record<string, unknown>;
    if (record.translations && typeof record.translations === "object") {
      return Object.fromEntries(
        Object.entries(record.translations).filter(
          (entry): entry is [string, string] =>
            typeof entry[1] === "string" && Boolean(entry[1].trim()),
        ),
      );
    }
    current = record.data;
  }
  return {};
}

export async function fetchMeetingSummaryDictionary(
  lang: UiLang,
  signal?: AbortSignal,
  module: MeetingSummaryModule = "ministry",
) {
  const baseUrl =
    process.env.NEXT_PUBLIC_API_URL?.replace(/\/$/, "") ||
    "http://localhost:3001/api/v1";
  const query = new URLSearchParams({
    module,
    page: "meeting_summary",
    language: lang,
  });
  const response = await fetch(`${baseUrl}/translations/dictionary?${query}`, {
    credentials: "include",
    cache: "no-store",
    signal,
    headers: { Accept: "application/json" },
  });
  if (!response.ok)
    throw new Error(
      `Could not load meeting summary translations (${response.status}).`,
    );
  return unwrapMeetingSummaryDictionary(await response.json());
}
