"use client";

import { useEffect, useMemo, useState } from "react";
import { usePathname } from "next/navigation";

import {
  cdcIssueMatrixText,
  type CdcIssueMatrixTranslation,
  type IssueMatrixLanguage,
} from "../components/cdc-issue-matrix-i18n";
import {
  getCdcIssueMatrixTranslationDictionary,
  type CdcIssueMatrixTranslationDictionary,
} from "../service/cdc-issue-matrix-translation-service";

const EMPTY_DICTIONARY: CdcIssueMatrixTranslationDictionary = {};

function textValue(
  api: CdcIssueMatrixTranslationDictionary,
  key: string,
  fallback: string,
): string {
  return api[key]?.trim() || fallback;
}

function templateValue(
  api: CdcIssueMatrixTranslationDictionary,
  key: string,
  fallback: (value: string) => string,
): (value: string) => string {
  const template = api[key]?.trim();

  if (!template) return fallback;

  return (value: string) =>
    template
      .split("{{value}}")
      .join(value)
      .split("{value}")
      .join(value);
}

function mergeApiLabels(
  fallback: CdcIssueMatrixTranslation,
  api: CdcIssueMatrixTranslationDictionary,
): CdcIssueMatrixTranslation {
  return {
    ...fallback,

    /*
     * IMPORTANT:
     * `title` is the sidebar/page identity label ("CDC Issue Matrix").
     * The screen heading is "All Issues", stored as `page.title`.
     *
     * If `page.title` is missing from the API, keep the original static
     * "All Issues". Do not fall back to API `title`, otherwise the sidebar
     * title would incorrectly replace the screen heading.
     */
    title: textValue(api, "page.title", fallback.title),
    breadcrumb: textValue(api, "breadcrumb", fallback.breadcrumb),
    search: textValue(api, "search", fallback.search),
    export: textValue(api, "export", fallback.export),
    exporting: textValue(api, "exporting", fallback.exporting),
    loadError: textValue(api, "error.load", fallback.loadError),
    newIssue: textValue(api, "new_issue", fallback.newIssue),
    list: textValue(api, "view.list", fallback.list),
    grid: textValue(api, "view.grid", fallback.grid),
    noData: textValue(api, "no_data", fallback.noData),
    viewDetail: textValue(api, "view_detail", fallback.viewDetail),
    statusLabels: {
      solved: textValue(api, "status.solved", fallback.statusLabels.solved),
      inProgress: textValue(api, "status.in_progress", fallback.statusLabels.inProgress),
      notAddressed: textValue(api, "status.not_addressed", fallback.statusLabels.notAddressed),
      draft: textValue(api, "status.draft", fallback.statusLabels.draft),
      saved: textValue(api, "status.saved", fallback.statusLabels.saved),
      newSubmission: textValue(api, "status.new_submission", fallback.statusLabels.newSubmission),
      select: textValue(api, "status.select", fallback.statusLabels.select),
      loading: textValue(api, "status.loading", fallback.statusLabels.loading),
    },
    actions: {
      more: textValue(api, "action.more", fallback.actions.more),
      edit: textValue(api, "action.edit", fallback.actions.edit),
      remove: textValue(api, "action.remove", fallback.actions.remove),
    },
    pagination: {
      previous: textValue(api, "pagination.previous", fallback.pagination.previous),
      next: textValue(api, "pagination.next", fallback.pagination.next),
    },

    deleteCdcIssue: textValue(
      api,
      "delete_issue.title",
      fallback.deleteCdcIssue,
    ),
    deleteCdcIssueQuestion: textValue(
      api,
      "delete_issue.question",
      fallback.deleteCdcIssueQuestion,
    ),
    cancel: textValue(api, "cancel", fallback.cancel),
    issueCreated: textValue(
      api,
      "toast.issue_created",
      fallback.issueCreated,
    ),
    issueUpdated: textValue(
      api,
      "toast.issue_updated",
      fallback.issueUpdated,
    ),
    issueDeleted: textValue(
      api,
      "toast.issue_deleted",
      fallback.issueDeleted,
    ),
    issueDeleteFailed: textValue(
      api,
      "toast.issue_delete_failed",
      fallback.issueDeleteFailed,
    ),

    totalIssues: textValue(
      api,
      "stats.total_issues",
      fallback.totalIssues,
    ),
    solved: textValue(api, "stats.solved", fallback.solved),
    inProgress: textValue(
      api,
      "stats.in_progress",
      fallback.inProgress,
    ),
    notAddressed: textValue(
      api,
      "stats.not_addressed",
      fallback.notAddressed,
    ),
    totalPrimaryAgencies: textValue(
      api,
      "stats.total_primary_agencies",
      fallback.totalPrimaryAgencies,
    ),

    filters: {
      categories: textValue(
        api,
        "filter.categories",
        fallback.filters.categories,
      ),
      status: textValue(
        api,
        "filter.status",
        fallback.filters.status,
      ),
      pswgs: textValue(
        api,
        "filter.working_group",
        fallback.filters.pswgs,
      ),
      year: textValue(
        api,
        "filter.year",
        fallback.filters.year,
      ),
      plenaryEscalation: textValue(
        api,
        "filter.plenary_escalation",
        fallback.filters.plenaryEscalation,
      ),
      escalated: textValue(
        api,
        "filter.escalated",
        fallback.filters.escalated,
      ),
      notEscalated: textValue(
        api,
        "filter.not_escalated",
        fallback.filters.notEscalated,
      ),
    },

    gridCard: {
      no: textValue(api, "grid.no", fallback.gridCard.no),
      ministry: textValue(
        api,
        "grid.ministry",
        fallback.gridCard.ministry,
      ),
      status: textValue(
        api,
        "grid.status",
        fallback.gridCard.status,
      ),
      categoryOfIssue: textValue(
        api,
        "grid.category",
        fallback.gridCard.categoryOfIssue,
      ),
      issue: textValue(api, "grid.issue", fallback.gridCard.issue),
      escalation: textValue(
        api,
        "grid.escalation",
        fallback.gridCard.escalation,
      ),
      issueDescription: textValue(
        api,
        "grid.issue_description",
        fallback.gridCard.issueDescription,
      ),
      recommendation: textValue(
        api,
        "grid.recommendation",
        fallback.gridCard.recommendation,
      ),
      rgcDecision: textValue(
        api,
        "grid.rgc_decision",
        fallback.gridCard.rgcDecision,
      ),
      remark: textValue(
        api,
        "grid.remark",
        fallback.gridCard.remark,
      ),
      plenary: textValue(
        api,
        "grid.plenary",
        fallback.gridCard.plenary,
      ),
      notPlenary: textValue(
        api,
        "grid.not_plenary",
        fallback.gridCard.notPlenary,
      ),
    },

    columns: {
      ...fallback.columns,
      id: textValue(
        api,
        "column.no",
        fallback.columns.id ?? "No.",
      ),
      workingGroup: textValue(
        api,
        "column.working_group",
        fallback.columns.workingGroup ?? "Working Group Name",
      ),
      issue: textValue(
        api,
        "column.issue",
        fallback.columns.issue ?? "Issue",
      ),
      category: textValue(
        api,
        "column.category",
        fallback.columns.category ?? "Category of Issue",
      ),
      issueDescription: textValue(
        api,
        "column.issue_description",
        fallback.columns.issueDescription ?? "Issue Description",
      ),
      recommendation: textValue(
        api,
        "column.recommendation",
        fallback.columns.recommendation ?? "Recommendation",
      ),
      governmentDecision: textValue(
        api,
        "column.rgc_decision",
        fallback.columns.governmentDecision ?? "RGC Decision",
      ),
      primaryAgency: textValue(
        api,
        "column.primary_agency",
        fallback.columns.primaryAgency ?? "Ministry",
      ),
      plenaryEscalation: textValue(
        api,
        "column.plenary_escalation",
        fallback.columns.plenaryEscalation ?? "Plenary Escalation",
      ),
      status: textValue(
        api,
        "column.status",
        fallback.columns.status ?? "Status",
      ),
      nextStep: textValue(
        api,
        "column.next_step",
        fallback.columns.nextStep ?? "Next Step",
      ),
      remark: textValue(
        api,
        "column.remark",
        fallback.columns.remark ?? "Remark",
      ),
      action: textValue(
        api,
        "column.action",
        fallback.columns.action ?? "Action",
      ),
    },

    plenaryEscalationDialog: {
      escalateTitle: textValue(
        api,
        "dialog.escalation.title",
        fallback.plenaryEscalationDialog.escalateTitle,
      ),
      escalateDescription: textValue(
        api,
        "dialog.escalation.description",
        fallback.plenaryEscalationDialog.escalateDescription,
      ),
      escalateConfirm: textValue(
        api,
        "dialog.escalation.confirm",
        fallback.plenaryEscalationDialog.escalateConfirm,
      ),
      removeTitle: textValue(
        api,
        "dialog.remove_escalation.title",
        fallback.plenaryEscalationDialog.removeTitle,
      ),
      removeDescription: textValue(
        api,
        "dialog.remove_escalation.description",
        fallback.plenaryEscalationDialog.removeDescription,
      ),
      removeConfirm: textValue(
        api,
        "dialog.remove_escalation.confirm",
        fallback.plenaryEscalationDialog.removeConfirm,
      ),
      cancel: textValue(
        api,
        "dialog.cancel",
        fallback.plenaryEscalationDialog.cancel,
      ),
    },

    plenaryEscalationToast: {
      escalated: textValue(
        api,
        "toast.escalated",
        fallback.plenaryEscalationToast.escalated,
      ),
      removed: textValue(
        api,
        "toast.escalation_removed",
        fallback.plenaryEscalationToast.removed,
      ),
      close: textValue(
        api,
        "toast.close",
        fallback.plenaryEscalationToast.close,
      ),
    },

    plenaryEscalationError: textValue(
      api,
      "error.plenary_escalation",
      fallback.plenaryEscalationError,
    ),

    statusChangeDialog: {
      title: textValue(
        api,
        "dialog.status_change.title",
        fallback.statusChangeDialog.title,
      ),
      description: templateValue(
        api,
        "dialog.status_change.description",
        fallback.statusChangeDialog.description,
      ),
      confirm: textValue(
        api,
        "dialog.status_change.confirm",
        fallback.statusChangeDialog.confirm,
      ),
      cancel: textValue(
        api,
        "dialog.status_change.cancel",
        fallback.statusChangeDialog.cancel,
      ),
    },

    ministryChangeDialog: {
      title: textValue(
        api,
        "dialog.ministry_change.title",
        fallback.ministryChangeDialog.title,
      ),
      description: templateValue(
        api,
        "dialog.ministry_change.description",
        fallback.ministryChangeDialog.description,
      ),
      confirm: textValue(
        api,
        "dialog.ministry_change.confirm",
        fallback.ministryChangeDialog.confirm,
      ),
      cancel: textValue(
        api,
        "dialog.ministry_change.cancel",
        fallback.ministryChangeDialog.cancel,
      ),
    },

    rowUpdateToast: {
      ministryUpdated: textValue(
        api,
        "toast.ministry_updated",
        fallback.rowUpdateToast.ministryUpdated,
      ),
      statusUpdated: textValue(
        api,
        "toast.status_updated",
        fallback.rowUpdateToast.statusUpdated,
      ),
    },

    rowUpdateError: textValue(
      api,
      "error.row_update",
      fallback.rowUpdateError,
    ),

    detail: {
      loading: textValue(api, "detail.loading", fallback.detail.loading),
      loadError: textValue(api, "detail.load_error", fallback.detail.loadError),
      notFound: textValue(api, "detail.not_found", fallback.detail.notFound),
      noDocument: textValue(api, "detail.no_document", fallback.detail.noDocument),
      back: textValue(api, "detail.back", fallback.detail.back),
      pageTitle: textValue(
        api,
        "detail.page_title",
        fallback.detail.pageTitle,
      ),
      breadcrumb: textValue(
        api,
        "detail.breadcrumb",
        fallback.detail.breadcrumb,
      ),

      submitDetailLabels: {
        submitDetail: textValue(
          api,
          "detail.submit_detail",
          fallback.detail.submitDetailLabels.submitDetail,
        ),
        ministryName: textValue(
          api,
          "detail.ministry_name",
          fallback.detail.submitDetailLabels.ministryName,
        ),
        submittedBy: textValue(
          api,
          "detail.submitted_by",
          fallback.detail.submitDetailLabels.submittedBy,
        ),
        submissionDate: textValue(
          api,
          "detail.submission_date",
          fallback.detail.submitDetailLabels.submissionDate,
        ),
        status: textValue(
          api,
          "detail.status",
          fallback.detail.submitDetailLabels.status,
        ),
        categoryOfIssues: textValue(
          api,
          "detail.category",
          fallback.detail.submitDetailLabels.categoryOfIssues,
        ),
        issueDocument: textValue(
          api,
          "detail.issue_document",
          fallback.detail.submitDetailLabels.issueDocument,
        ),
        ministry: textValue(
          api,
          "detail.private_sector_wg",
          fallback.detail.submitDetailLabels.ministry,
        ),
        plenaryEscalation: textValue(
          api,
          "detail.plenary_escalation",
          fallback.detail.submitDetailLabels.plenaryEscalation,
        ),
      },

      sections: {
        issueDescription: textValue(
          api,
          "detail.section.issue_description",
          fallback.detail.sections.issueDescription,
        ),
        recommendation: textValue(
          api,
          "detail.section.recommendation",
          fallback.detail.sections.recommendation,
        ),
        rgcDecision: textValue(
          api,
          "detail.section.rgc_decision",
          fallback.detail.sections.rgcDecision,
        ),
        indicators: textValue(
          api,
          "detail.section.indicators",
          fallback.detail.sections.indicators,
        ),
        progressSolution: textValue(
          api,
          "detail.section.progress_solution",
          fallback.detail.sections.progressSolution,
        ),
        implementationChallenges: textValue(
          api,
          "detail.section.implementation_challenges",
          fallback.detail.sections.implementationChallenges,
        ),
        request: textValue(
          api,
          "detail.section.request",
          fallback.detail.sections.request,
        ),
        nextStep: textValue(
          api,
          "detail.section.next_step",
          fallback.detail.sections.nextStep,
        ),
        sourceOfVerification: textValue(
          api,
          "detail.section.source_of_verification",
          fallback.detail.sections.sourceOfVerification,
        ),
        linkToVerificationSource: textValue(
          api,
          "detail.section.link_to_verification_source",
          fallback.detail.sections.linkToVerificationSource,
        ),
      },
    },
  };
}

export function useCdcIssueMatrixApiLabels(
  language: IssueMatrixLanguage,
): CdcIssueMatrixTranslationDictionary {
  const pathname = usePathname();
  const moduleName = pathname.startsWith("/cefp") ? "cefp" : "cdc";
  const scope = `${moduleName}:${language}`;

  const [labelState, setLabelState] = useState<{
    scope: string;
    labels: CdcIssueMatrixTranslationDictionary;
  }>({ scope: "", labels: {} });

  useEffect(() => {
    let cancelled = false;

    const load = async () => {
      try {
        const dictionary =
          await getCdcIssueMatrixTranslationDictionary(
            language,
            moduleName,
          );

        if (!cancelled) {
          setLabelState({ scope, labels: dictionary });
        }
      } catch {
        if (!cancelled) {
          // No API / empty API => caller keeps its original static fallback.
          setLabelState({ scope, labels: {} });
        }
      }
    };

    void load();

    /*
     * If an admin edits a label in Translation Management in another tab,
     * opening/returning to this application must fetch the latest dictionary
     * instead of keeping the dictionary loaded when the page first opened.
     */
    const handleFocus = () => {
      void load();
    };

    const handleVisibilityChange = () => {
      if (document.visibilityState === "visible") {
        void load();
      }
    };

    window.addEventListener("focus", handleFocus);
    document.addEventListener(
      "visibilitychange",
      handleVisibilityChange,
    );

    return () => {
      cancelled = true;
      window.removeEventListener("focus", handleFocus);
      document.removeEventListener(
        "visibilitychange",
        handleVisibilityChange,
      );
    };
  }, [language, moduleName, scope]);

  return labelState.scope === scope ? labelState.labels : EMPTY_DICTIONARY;
}

export function useCdcIssueMatrixTranslations(
  language: IssueMatrixLanguage,
): CdcIssueMatrixTranslation {
  const pathname = usePathname();
  const moduleName = pathname.startsWith("/cefp") ? "cefp" : "cdc";
  const scope = `${moduleName}:${language}`;

  const [labelState, setLabelState] = useState<{
    scope: string;
    labels: CdcIssueMatrixTranslationDictionary;
  }>({ scope: "", labels: {} });

  useEffect(() => {
    let cancelled = false;

    const load = async () => {
      try {
        const dictionary =
          await getCdcIssueMatrixTranslationDictionary(
            language,
            moduleName,
          );

        if (!cancelled) {
          setLabelState({ scope, labels: dictionary });
        }
      } catch {
        if (!cancelled) {
          // API missing/error => preserve the existing static labels.
          setLabelState({ scope, labels: {} });
        }
      }
    };

    void load();

    const handleFocus = () => {
      void load();
    };

    const handleVisibilityChange = () => {
      if (document.visibilityState === "visible") {
        void load();
      }
    };

    window.addEventListener("focus", handleFocus);
    document.addEventListener(
      "visibilitychange",
      handleVisibilityChange,
    );

    return () => {
      cancelled = true;
      window.removeEventListener("focus", handleFocus);
      document.removeEventListener(
        "visibilitychange",
        handleVisibilityChange,
      );
    };
  }, [language, moduleName, scope]);

  const staticLabels =
    cdcIssueMatrixText[language] ??
    cdcIssueMatrixText.en;

  const apiLabels = labelState.scope === scope ? labelState.labels : EMPTY_DICTIONARY;
  return useMemo(
    () => mergeApiLabels(staticLabels, apiLabels),
    [apiLabels, staticLabels],
  );
}
