import {
  i18n,
  type UiLang,
  type MeetingRequestText,
} from "./meeting-request-i18n";

// title is reserved for the sidebar/Admin page name, not the visible heading.
const keys: Record<string, string> = {
  filterWorkingGroup: "filter.working_group",
  filterGovernmentAgency: "filter.government_agency",
  filterMeetingStatus: "filter.meeting_status",
  filterMeetingDate: "filter.meeting_date",
  meetingRequests: "page_title",
  title: "form.title",
  breadcrumbMeetingRequests: "subtitle",
  calendar: "view.calendar",
  exportAsXlsx: "export_xlsx",
  newMeetingRequest: "new_request",
  workingGroup: "table.working_group",
  governmentAgency: "table.government_agency",
  meetingStatus: "table.meeting_status",
  meetingDate: "table.meeting_date",
  allMeetingRequest: "view.all_meeting_request",
  no: "table.no",
  meetingTitle: "table.meeting_title",
  meetingDescription: "table.meeting_description",
  issuesCount: "table.issue_count",
  meetingRequest: "table.request_letter",
  action: "table.action",
};

export function meetingRequestTranslationKey(path: string): string {
  return (
    keys[path] ??
    path
      .replace(/^statuses\./, "status.")
      .replace(/^filterPanel\./, "filter.")
      .replace(/([a-z0-9])([A-Z])/g, "$1_$2")
      .replace(/ /g, "_")
      .toLowerCase()
  );
}

export function unwrapMeetingRequestDictionary(
  value: unknown,
): Record<string, string> {
  for (
    let depth = 0;
    depth < 5 && value && typeof value === "object";
    depth++
  ) {
    const record = value 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" && !!entry[1].trim(),
        ),
      );
    }
    value = record.data;
  }
  return {};
}

export function resolveMeetingRequestText(
  lang: UiLang,
  dictionary: Record<string, string>,
): MeetingRequestText {
  function visit(value: object, prefix = ""): object {
    return Object.fromEntries(
      Object.entries(value).map(([key, fallback]) => {
        const path = prefix ? prefix + "." + key : key;
        const translated = dictionary[meetingRequestTranslationKey(path)];
        return [
          key,
          typeof fallback === "string"
            ? typeof translated === "string" && translated.trim()
              ? translated
              : fallback
            : visit(fallback, path),
        ];
      }),
    );
  }
  return visit(i18n(lang)) as MeetingRequestText;
}

export async function fetchMeetingRequestDictionary(
  language: UiLang,
  signal?: AbortSignal,
) {
  const base = (
    process.env.NEXT_PUBLIC_API_URL || "http://localhost:3001/api/v1"
  ).replace(/\/$/, "");
  const query = new URLSearchParams({
    module: "pswg",
    page: "meeting_requests",
    language,
  });
  const response = await fetch(base + "/translations/dictionary?" + query, {
    credentials: "include",
    cache: "no-store",
    signal,
  });
  if (!response.ok)
    throw new Error("Could not load meeting request translations");
  return unwrapMeetingRequestDictionary(await response.json());
}
