"use client";

import { useEffect, useMemo, useRef } from "react";

import { useAppLanguage } from "@/components/providers/app-language-provider";
import { CreateIssueDialog } from "@/features/pswg/working-group-issues/components/create-issuses";

import { useCdcIssueMatrixApiLabels } from "../hook/use-cdc-issue-matrix-translations";
import { normalizeCdcIssueMatrixLanguage } from "./cdc-issue-matrix-i18n";

type CdcCreateIssueDialogProps = {
  open: boolean;
  issueId?: number;
  onClose: () => void;
  onCreated?: () => void;
  onSaved?: () => void;
};

type LabelRule = {
  key: string;
  staticTexts: string[];
};

type PlaceholderRule = {
  key: string;
  staticTexts: string[];
};

const LABEL_RULES: LabelRule[] = [
  {
    key: "form.add_issue.title",
    staticTexts: ["Add Issue", "បន្ថែមបញ្ហា"],
  },
  {
    key: "form.government_agency.label",
    staticTexts: [
      "Government Agency",
      "ក្រសួង/ស្ថាប័នរដ្ឋ",
      "ស្ថាប័នរាជរដ្ឋាភិបាល",
    ],
  },
  {
    key: "form.issue.label",
    staticTexts: ["Issue", "បញ្ហា"],
  },
  {
    key: "form.issue_category.label",
    staticTexts: [
      "Issue Category",
      "Category of Issue",
      "Category of Issues",
      "ប្រភេទបញ្ហា",
    ],
  },
  {
    key: "form.issue_description.label",
    staticTexts: [
      "Issue Description",
      "Description of the Issue",
      "ការពិពណ៌នាបញ្ហា",
      "ការពិពណ៌នាអំពីបញ្ហា",
    ],
  },
  {
    key: "form.recommendation.label",
    staticTexts: ["Recommendation", "អនុសាសន៍"],
  },
  {
    key: "form.attachment.label",
    staticTexts: ["Attachment", "Issue Attachment", "ឯកសារភ្ជាប់"],
  },
  {
    key: "form.attachment.upload",
    staticTexts: [
      "Click to upload or drag and drop",
      "ចុចដើម្បីបញ្ចូលឯកសារ ឬអូសទម្លាក់",
    ],
  },
  {
    key: "form.attachment.hint",
    staticTexts: ["pdf 10MB", "PDF 10MB", "PDF អតិបរមា 10MB"],
  },
  {
    key: "form.second_agency.label",
    staticTexts: ["Second Agency", "ស្ថាប័នទី២"],
  },
  {
    key: "form.third_agency.label",
    staticTexts: ["Third Agency", "ស្ថាប័នទី៣"],
  },
  {
    key: "form.fourth_agency.label",
    staticTexts: ["Fourth Agency", "ស្ថាប័នទី៤"],
  },
  {
    key: "form.fifth_agency.label",
    staticTexts: ["Fifth Agency", "ស្ថាប័នទី៥"],
  },
  {
    key: "form.button.draft",
    staticTexts: ["Draft", "រក្សាទុកព្រាង"],
  },
  {
    key: "form.button.save",
    staticTexts: ["Save", "រក្សាទុក"],
  },
];

const PLACEHOLDER_RULES: PlaceholderRule[] = [
  {
    key: "form.working_group.placeholder",
    staticTexts: [
      "Working Group Name",
      "Select working group name",
      "Select Working Group",
      "ជ្រើសរើសក្រុមការងារ",
    ],
  },
  {
    key: "form.government_agency.placeholder",
    staticTexts: [
      "Select Agency",
      "Select agency",
      "Select Ministry",
      "ជ្រើសរើសស្ថាប័ន",
      "ជ្រើសរើសក្រសួង",
    ],
  },
  {
    key: "form.issue.placeholder",
    staticTexts: [
      "Write Issue title",
      "Write Issue Title",
      "សរសេរចំណងជើងបញ្ហា",
    ],
  },
  {
    key: "form.issue_category.placeholder",
    staticTexts: [
      "Select issue category",
      "Select category of issue",
      "Select category",
      "ជ្រើសរើសប្រភេទបញ្ហា",
    ],
  },
  {
    key: "form.issue_description.placeholder",
    staticTexts: [
      "Write description ........",
      "Write description ..........",
      "Write description .",
      "Write description",
      "សរសេរការពិពណ៌នា ........",
      "សរសេរការពិពណ៌នាអំពីបញ្ហា...",
    ],
  },
  {
    key: "form.recommendation.placeholder",
    staticTexts: [
      "Write Recommendation..........",
      "Write Recommendation...........",
      "Write Recommendation .",
      "Write Recommendation.",
      "Write Recommendation",
      "សរសេរអនុសាសន៍..........",
      "សរសេរអនុសាសន៍...",
    ],
  },
];

const DISPLAY_PLACEHOLDER_RULES: LabelRule[] = [
  {
    key: "form.government_agency.placeholder",
    staticTexts: [
      "Select Agency",
      "Select agency",
      "Select Ministry",
      "ជ្រើសរើសស្ថាប័ន",
      "ជ្រើសរើសក្រសួង",
    ],
  },
  {
    key: "form.issue_category.placeholder",
    staticTexts: [
      "Select issue category",
      "Select category of issue",
      "Select category",
      "ជ្រើសរើសប្រភេទបញ្ហា",
    ],
  },
  {
    key: "form.issue_description.placeholder",
    staticTexts: [
      "Write description ........",
      "Write description ..........",
      "Write description .",
      "Write description",
      "សរសេរការពិពណ៌នា ........",
      "សរសេរការពិពណ៌នាអំពីបញ្ហា...",
    ],
  },
  {
    key: "form.recommendation.placeholder",
    staticTexts: [
      "Write Recommendation..........",
      "Write Recommendation...........",
      "Write Recommendation .",
      "Write Recommendation.",
      "Write Recommendation",
      "សរសេរអនុសាសន៍..........",
      "សរសេរអនុសាសន៍...",
    ],
  },
];

function normalizeText(value: string | null | undefined): string {
  return String(value ?? "")
    .replace(/\s+/g, " ")
    .trim();
}

function findActiveIssueDialogRoot(): HTMLElement | null {
  const candidates = Array.from(
    document.querySelectorAll<HTMLElement>(
      '[role="dialog"], .MuiDrawer-paper, .MuiDialog-paper',
    ),
  ).filter((element) => {
    const style = window.getComputedStyle(element);
    return style.display !== "none" && style.visibility !== "hidden";
  });

  if (candidates.length === 0) {
    return null;
  }

  // The Create/Edit Issue drawer is rendered last in the modal portal.
  return candidates[candidates.length - 1] ?? null;
}

function replaceWorkingGroupTexts(
  root: HTMLElement,
  labelText: string | undefined,
  placeholderText: string | undefined,
  previousLabel: string | undefined,
  previousPlaceholder: string | undefined,
): void {
  if (!labelText && !placeholderText) {
    return;
  }

  const accepted = new Set(
    [
      "Working Group Name",
      "ឈ្មោះក្រុមការងារ",
      "ជ្រើសរើសក្រុមការងារ",
      previousLabel ?? "",
      previousPlaceholder ?? "",
    ]
      .map(normalizeText)
      .filter(Boolean),
  );

  const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
  const matches: Text[] = [];

  let currentNode = walker.nextNode();
  while (currentNode) {
    const textNode = currentNode as Text;
    if (accepted.has(normalizeText(textNode.nodeValue))) {
      matches.push(textNode);
    }
    currentNode = walker.nextNode();
  }

  // In the real CreateIssueDialog DOM the required field label is rendered
  // before the select's displayed placeholder. Keep that distinction so the
  // label can become "Working Group Name Test" while the select can keep the
  // API placeholder "Working Group Name".
  const setNodeText = (textNode: Text | undefined, nextText: string | undefined) => {
    if (
      !textNode ||
      !nextText?.trim() ||
      normalizeText(textNode.nodeValue) === normalizeText(nextText)
    ) {
      return;
    }

    const originalValue = textNode.nodeValue ?? "";
    const leadingSpace = originalValue.match(/^\s*/)?.[0] ?? "";
    const trailingSpace = originalValue.match(/\s*$/)?.[0] ?? "";
    textNode.nodeValue = `${leadingSpace}${nextText}${trailingSpace}`;
  };

  // Never use the placeholder API value to overwrite the field label when
  // the label key itself is absent. Missing API keys must keep static UI.
  setNodeText(matches[0], labelText);
  setNodeText(matches[1], placeholderText);
}

function replaceTextNodes(
  root: HTMLElement,
  sourceTexts: string[],
  previousText: string | undefined,
  nextText: string,
): void {
  const accepted = new Set(
    [...sourceTexts, previousText ?? ""]
      .map(normalizeText)
      .filter(Boolean),
  );

  const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
  const textNodes: Text[] = [];

  let currentNode = walker.nextNode();
  while (currentNode) {
    textNodes.push(currentNode as Text);
    currentNode = walker.nextNode();
  }

  for (const textNode of textNodes) {
    const current = normalizeText(textNode.nodeValue);

    if (!accepted.has(current) || current === normalizeText(nextText)) {
      continue;
    }

    const originalValue = textNode.nodeValue ?? "";
    const leadingSpace = originalValue.match(/^\s*/)?.[0] ?? "";
    const trailingSpace = originalValue.match(/\s*$/)?.[0] ?? "";

    textNode.nodeValue = `${leadingSpace}${nextText}${trailingSpace}`;
  }
}

function replacePlaceholders(
  root: HTMLElement,
  sourceTexts: string[],
  previousText: string | undefined,
  nextText: string,
): void {
  const accepted = new Set(
    [...sourceTexts, previousText ?? ""]
      .map(normalizeText)
      .filter(Boolean),
  );

  const elements = root.querySelectorAll<HTMLElement>(
    "input[placeholder], textarea[placeholder]",
  );

  elements.forEach((element) => {
    const current = normalizeText(element.getAttribute("placeholder"));

    if (accepted.has(current) && current !== normalizeText(nextText)) {
      element.setAttribute("placeholder", nextText);
    }
  });
}

export function CdcCreateIssueDialog({
  open,
  issueId,
  onClose,
  onCreated,
  onSaved,
}: CdcCreateIssueDialogProps) {
  const { language } = useAppLanguage();
  const matrixLanguage = normalizeCdcIssueMatrixLanguage(language);
  const apiLabels = useCdcIssueMatrixApiLabels(matrixLanguage);
  const previousApiLabelsRef = useRef<Record<string, string>>({});

  const activeLabels = useMemo(() => {
    const values: Record<string, string> = {};

    for (const [key, value] of Object.entries(apiLabels)) {
      const clean = value?.trim();
      if (clean) {
        values[key] = clean;
      }
    }

    return values;
  }, [apiLabels]);

  useEffect(() => {
    if (!open) {
      return;
    }

    let frameId = 0;
    let observer: MutationObserver | null = null;

    const applyTranslations = () => {
      const root = findActiveIssueDialogRoot();
      if (!root) {
        return;
      }

      replaceWorkingGroupTexts(
        root,
        activeLabels["form.working_group.label"],
        activeLabels["form.working_group.placeholder"],
        previousApiLabelsRef.current["form.working_group.label"],
        previousApiLabelsRef.current["form.working_group.placeholder"],
      );

      for (const rule of LABEL_RULES) {
        const nextText = activeLabels[rule.key];
        if (!nextText) {
          continue;
        }

        replaceTextNodes(
          root,
          rule.staticTexts,
          previousApiLabelsRef.current[rule.key],
          nextText,
        );
      }

      for (const rule of DISPLAY_PLACEHOLDER_RULES) {
        const nextText = activeLabels[rule.key];
        if (!nextText) {
          continue;
        }

        replaceTextNodes(
          root,
          rule.staticTexts,
          previousApiLabelsRef.current[rule.key],
          nextText,
        );
      }

      for (const rule of PLACEHOLDER_RULES) {
        const nextText = activeLabels[rule.key];
        if (!nextText) {
          continue;
        }

        replacePlaceholders(
          root,
          rule.staticTexts,
          previousApiLabelsRef.current[rule.key],
          nextText,
        );
      }

      previousApiLabelsRef.current = {
        ...previousApiLabelsRef.current,
        ...activeLabels,
      };
    };

    const scheduleApply = () => {
      window.cancelAnimationFrame(frameId);
      frameId = window.requestAnimationFrame(applyTranslations);
    };

    scheduleApply();

    observer = new MutationObserver(scheduleApply);
    observer.observe(document.body, {
      childList: true,
      subtree: true,
      characterData: true,
      attributes: true,
      attributeFilter: ["placeholder"],
    });

    return () => {
      window.cancelAnimationFrame(frameId);
      observer?.disconnect();
    };
  }, [activeLabels, open]);

  return (
    <CreateIssueDialog
      mode="cdc"
      open={open}
      onClose={onClose}
      {...(issueId !== undefined ? { issueId } : {})}
      {...(onCreated ? { onCreated } : {})}
      {...(onSaved ? { onSaved } : {})}
    />
  );
}
