// PrefixManagement.tsx
import React, { useState, useEffect, useMemo, useRef } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { Card, CardHeader, CardTitle } from "@/shared/common/ui/card";
import { Button } from "@/shared/common/ui/button";
import { Plus } from "lucide-react";
import { usePositions } from "@/user-management/hooks/usePosition";
import { t } from "i18next";
import { PrefixSuffixTable } from "./PrefixSuffixTable";
import { PrefixModal } from "./PrefixModal";
import {
  useCCPrefixesList,
  useCCSuffixesList,
  useDeletePrefix,
  useDeleteSuffix,
  usePositionPrefixesList,
  usePrefixesList,
  useSuffixesList,
} from "@/user-management/hooks/usePrefixSuffixes";
import {
  useGetReferenceNumbers,
} from "@/shared/hooks/useReferenceNumberPrefixes";
import { useDeleteReferenceNumber } from "@/shared/hooks/useReferenceNumberPrefixes";
import { useErrorHandler } from "@/shared/hooks/useErrorHandler";
import { toast } from "sonner";
import { TagBasedReferenceNumbers } from "./TagBasedReferenceNumbers";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/shared/common/ui/alert-dialog";

export type PrefixTabType =
  | "internal"
  | "external"
  | "internal_memo"
  | "branch"
  | "tag-based-reference"
  | "referenceNumber"
  | "positionPrefix";

const tabs: { id: PrefixTabType; label: string }[] = [
  { id: "internal", label: "nav.internal" },
  { id: "external", label: "nav.external" },
  { id: "internal_memo", label: "nav.internal_memo" },
  { id: "branch", label: "nav.branch" },
  { id: "tag-based-reference", label: "nav.tagBasedReference" },
  { id: "referenceNumber", label: "userRecord.Reference" },
  { id: "positionPrefix", label: "contentManagement.positionPrefixes" },
];

interface PrefixManagementProps {
  unitId: string;
  initialTab?: PrefixTabType;
}

const getDefaultCardForTab = (tab: PrefixTabType): string => {
  if (tab === "positionPrefix") return "internalPrefix";
  if (tab === "referenceNumber") return "reference";
  return "prefix";
};

export const PrefixAndSuffix = ({
  unitId,
  initialTab = "internal",
}: PrefixManagementProps) => {
  const { handleError } = useErrorHandler(t);
  const [activeTab, setActiveTab] = useState<PrefixTabType>(initialTab);
  const [activeCard, setActiveCard] = useState<string>(
    getDefaultCardForTab(initialTab),
  );
  const [modalOpen, setModalOpen] = useState(false);
  const [modalConfig, setModalConfig] = useState<{
    cardType: string;
    recordType: PrefixTabType;
    editingItem?: any;
  } | null>(null);

  const queryClient = useQueryClient();
  const { mutateAsync: deletePrefix } = useDeletePrefix();
  const { mutateAsync: deleteSuffix } = useDeleteSuffix();
  const { mutateAsync: deleteReferenceNumber, isPending: isDeletingReference } =
    useDeleteReferenceNumber();
  const [pendingReferenceDelete, setPendingReferenceDelete] = useState<{
    id: string;
    type: string;
  } | null>(null);

  // Fetch positions for the position prefix tab
  const { usePositionListByUnitId } = usePositions();
  const { data: positionsResponse } = usePositionListByUnitId(unitId, {
    take: 1000,
    skip: 0,
  });
  const positions = positionsResponse?.items || [];

  // Update active tab when the sidebar sub‑menu changes
  useEffect(() => {
    setActiveTab(initialTab);
    setActiveCard(getDefaultCardForTab(initialTab));
  }, [initialTab]);

  useEffect(() => {
    setActiveCard(getDefaultCardForTab(activeTab));
  }, [activeTab]);

  const handleAddClick = (cardType: string) => {
    setModalConfig({ cardType, recordType: activeTab });
    setModalOpen(true);
  };

  const handleEdit = (item: any) => {
    setModalConfig({
      cardType: item.type, // e.g., "prefix", "suffix", "reference"
      recordType: activeTab,
      editingItem: item,
    });
    setModalOpen(true);
  };

  const handleDelete = async (id: string, type: string, recordType: string) => {
    console.log("Delete requested for:", { id, type, recordType });
    const isReferenceType =
      type === "reference" ||
      type === "externalReference" ||
      type === "internalMemoReference";

    if (isReferenceType) {
      setPendingReferenceDelete({ id, type });
      return;
    }

    const isPrefixType =
      type === "prefix" ||
      type === "prefixCC" ||
      type === "internalPrefix" ||
      type === "externalPrefix" ||
      type === "internalMemoPrefix";
    const isForCC = type === "prefixCC" || type === "suffixCC";
    const resolvedRecordTypeKey =
      recordType ||
      (type === "internalPrefix"
        ? "internal"
        : type === "externalPrefix"
          ? "external"
          : type === "internalMemoPrefix"
            ? "internal_memo"
            : activeTab);

    try {
      if (isPrefixType) {
        await deletePrefix({
          id,
          unitId,
          recordTypeKey: resolvedRecordTypeKey,
          isForCC,
        });

        if (activeTab === "positionPrefix") {
          queryClient.invalidateQueries({
            queryKey: ["prefixes-by-position", unitId, resolvedRecordTypeKey],
          });
        }
      } else {
        await deleteSuffix({
          id,
          unitId,
          recordTypeKey: resolvedRecordTypeKey,
          isForCC,
        });
      }

      queryClient.invalidateQueries({ queryKey: ["prefixSuffix"] });
      toast.success(t("contentManagement.deleted"));
    } catch (error) {
      void handleError(error);
    }
  };

  const confirmReferenceDelete = async () => {
    if (!pendingReferenceDelete) return;
    if (!pendingReferenceDelete.id) {
      toast.error(
        t(
          "prefixes.deleteMissingId",
          "Unable to delete: missing configuration id.",
        ),
      );
      return;
    }
    const sequenceType =
      pendingReferenceDelete.type === "externalReference"
        ? "external"
        : pendingReferenceDelete.type === "internalMemoReference"
          ? "internal_memo"
          : "internal";
    try {
      await deleteReferenceNumber({
        unitId,
        id: pendingReferenceDelete.id,
        payload: { recordSequenceTypes: [sequenceType] },
      });
      setPendingReferenceDelete(null);
      toast.success(t("contentManagement.deleted"));
    } catch (error) {
      void handleError(error);
    }
  };

  const handleModalClose = () => {
    setModalOpen(false);
    setModalConfig(null);
  };

  const handleModalSuccess = () => {
    const targetCardType = modalConfig?.cardType ?? activeCard;
    const targetTab = modalConfig?.recordType ?? activeTab;

    const targetIsCC =
      targetCardType === "prefixCC" || targetCardType === "suffixCC";
    const targetIsPrefix =
      targetCardType === "prefix" ||
      targetCardType === "prefixCC" ||
      targetCardType === "internalPrefix" ||
      targetCardType === "externalPrefix" ||
      targetCardType === "internalMemoPrefix" ||
      targetTab === "referenceNumber";

    const targetRecordTypeKey =
      targetTab === "referenceNumber"
        ? targetCardType
        : targetTab === "positionPrefix"
          ? targetCardType === "internalPrefix"
            ? "internal"
            : targetCardType === "internalMemoPrefix"
              ? "internal_memo"
              : "external"
          : targetTab;

    if (targetIsPrefix) {
      if (targetTab === "positionPrefix") {
        queryClient.invalidateQueries({
          queryKey: ["prefixes-by-position", unitId, targetRecordTypeKey],
        });
      }
      queryClient.invalidateQueries({
        queryKey: ["prefixes", unitId, targetRecordTypeKey, { cc: targetIsCC }],
      });
    } else {
      queryClient.invalidateQueries({
        queryKey: ["suffixes", unitId, targetRecordTypeKey, { cc: targetIsCC }],
      });
    }

    // Keep old key invalidation for legacy consumers.
    queryClient.invalidateQueries({ queryKey: ["prefixSuffix"] });
    handleModalClose();
  };

  // Define cards for the active tab
  const getCards = () => {
    if (activeTab === "positionPrefix") {
      return [
        { id: "internalPrefix", label: "contentManagement.internalPrefix" },
        { id: "externalPrefix", label: "contentManagement.externalPrefix" },
        {
          id: "internalMemoPrefix",
          label: "contentManagement.internalMemoPrefix",
        },
      ];
    }
    if (activeTab === "referenceNumber") {
      return [
        { id: "reference", label: "contentManagement.reference" },
        {
          id: "externalReference",
          label: "contentManagement.externalReference",
        },
        {
          id: "internalMemoReference",
          label: "contentManagement.internalMemoReference",
        },
      ];
    }
    // internal, external, internal_memo
    return [
      { id: "prefix", label: "contentManagement.prefix" },
      { id: "suffix", label: "contentManagement.suffix" },
      { id: "prefixCC", label: "contentManagement.prefixCC" },
      { id: "suffixCC", label: "contentManagement.suffixCC" },
    ];
  };

  const cards = getCards();
  useEffect(() => {
    if (!cards.some((card) => card.id === activeCard)) {
      setActiveCard(cards[0]?.id || getDefaultCardForTab(activeTab));
    }
  }, [cards, activeCard, activeTab]);

  const isCC = activeCard === "prefixCC" || activeCard === "suffixCC";
  const isReferenceTab = activeTab === "referenceNumber";
  const isPositionPrefixTab = activeTab === "positionPrefix";
  const isTagBasedTab = activeTab === "tag-based-reference";
  const isPrefix =
    activeCard === "prefix" ||
    activeCard === "prefixCC" ||
    activeCard === "internalPrefix" ||
    activeCard === "externalPrefix" ||
    activeCard === "internalMemoPrefix" ||
    isReferenceTab;

  const positionRecordTypeKey =
    activeCard === "internalPrefix"
      ? "internal"
      : activeCard === "externalPrefix"
        ? "external"
        : activeCard === "internalMemoPrefix"
          ? "internal_memo"
          : "";
  const recordTypeKey =
    activeTab === "positionPrefix" ? positionRecordTypeKey : activeTab;

  const {
    data: referenceNumbersData,
    isLoading: isLoadingReferenceNumbers,
    error: referenceNumbersError,
  } = useGetReferenceNumbers(isReferenceTab ? unitId : "");

  const {
    data: prefixesData,
    isLoading: isLoadingPrefixes,
    error: prefixesError,
  } = usePrefixesList(
    unitId,
    isPrefix &&
      !isCC &&
      !isReferenceTab &&
      !isPositionPrefixTab &&
      !isTagBasedTab
      ? recordTypeKey
      : "",
    0,
    1000,
  );
  const {
    data: positionPrefixesData,
    isLoading: isLoadingPositionPrefixes,
    error: positionPrefixesError,
  } = usePositionPrefixesList(
    unitId,
    isPositionPrefixTab ? positionRecordTypeKey : "",
    0,
    1000,
  );
  const {
    data: ccPrefixesData,
    isLoading: isLoadingCCPrefixes,
    error: ccPrefixesError,
  } = useCCPrefixesList(
    unitId,
    isPrefix && isCC && !isReferenceTab ? recordTypeKey : "",
    0,
    1000,
  );
  const {
    data: suffixesData,
    isLoading: isLoadingSuffixes,
    error: suffixesError,
  } = useSuffixesList(
    unitId,
    !isPrefix && !isCC && !isReferenceTab ? recordTypeKey : "",
    0,
    1000,
  );
  const {
    data: ccSuffixesData,
    isLoading: isLoadingCCSuffixes,
    error: ccSuffixesError,
  } = useCCSuffixesList(
    unitId,
    !isPrefix && isCC && !isReferenceTab ? recordTypeKey : "",
    0,
    1000,
  );

  const firstQueryError = useMemo(
    () =>
      [
        referenceNumbersError,
        positionPrefixesError,
        prefixesError,
        ccPrefixesError,
        suffixesError,
        ccSuffixesError,
      ].find(Boolean),
    [
      referenceNumbersError,
      positionPrefixesError,
      prefixesError,
      ccPrefixesError,
      suffixesError,
      ccSuffixesError,
    ],
  );

  const lastHandledErrorRef = useRef<unknown>(null);
  useEffect(() => {
    if (!firstQueryError || firstQueryError === lastHandledErrorRef.current) {
      return;
    }
    lastHandledErrorRef.current = firstQueryError;
    void handleError(firstQueryError);
  }, [firstQueryError, handleError]);
  const referenceNumbers = referenceNumbersData?.data || [];
  const referenceNumberPrefix = referenceNumbers?.find(
    (rn: any) => rn.name === "referenceNumberPrefix",
  );

  const externalReferenceNumberPrefix = referenceNumbers?.find(
    (rn: any) => rn.name === "externalReferenceNumberPrefix",
  );

  const internalMemoReferenceNumberPrefix = referenceNumbers?.find(
    (rn: any) => rn.name === "internalMemoReferenceNumberPrefix",
  );

  const getAmValue = (value: any): string => {
    if (!value) return "";

    if (typeof value === "string") {
      try {
        const parsed = JSON.parse(value);
        return parsed?.am ?? value;
      } catch {
        return value;
      }
    }

    if (typeof value === "object") {
      return value?.am ?? "";
    }

    return "";
  };
  const branchItems = [
    {
      id: unitId,
      type: "reference",
      recordTypeKey: "reference",
      isForCC: false,
      name: {
        am: getAmValue(referenceNumberPrefix?.number),
        en: getAmValue(referenceNumberPrefix?.number?.en),
      },
      count: referenceNumberPrefix?.count ?? 0,
      sequenceId: referenceNumberPrefix?.sequenceId,
    },
    {
      id: unitId,
      type: "externalReference",
      recordTypeKey: "externalReference",
      isForCC: false,
      name: {
        am: getAmValue(externalReferenceNumberPrefix?.number?.am),
        en: getAmValue(externalReferenceNumberPrefix?.number?.en),
      },
      count: externalReferenceNumberPrefix?.count ?? 0,
      sequenceId: externalReferenceNumberPrefix?.sequenceId,
    },
    {
      id: unitId,
      type: "internalMemoReference",
      recordTypeKey: "internalMemoReference",
      isForCC: false,
      name: {
        am: getAmValue(internalMemoReferenceNumberPrefix?.number?.am),
        en: getAmValue(internalMemoReferenceNumberPrefix?.number?.en),
      },
      count: internalMemoReferenceNumberPrefix?.count ?? 0,
      sequenceId: internalMemoReferenceNumberPrefix?.sequenceId,
    },
  ].filter((item) => item.type === activeCard);

  const activeResponse = isPositionPrefixTab
    ? positionPrefixesData
    : isPrefix
      ? isCC
        ? ccPrefixesData
        : prefixesData
      : isCC
        ? ccSuffixesData
        : suffixesData;

  const items = isReferenceTab
    ? branchItems
    : activeResponse?.data?.items?.map((item: any) => ({
        ...item,
        type:
          activeTab === "positionPrefix"
            ? item.recordTypeKey === "internal"
              ? "internalPrefix"
              : item.recordTypeKey === "internal_memo"
                ? "internalMemoPrefix"
                : "externalPrefix"
            : isPrefix
              ? isCC
                ? "prefixCC"
                : "prefix"
              : isCC
                ? "suffixCC"
                : "suffix",
        isForCC: isCC || item.isForCC,
      })) || [];

  const isLoading =
    isLoadingReferenceNumbers ||
    isLoadingPositionPrefixes ||
    isLoadingPrefixes ||
    isLoadingCCPrefixes ||
    isLoadingSuffixes ||
    isLoadingCCSuffixes;

  return (
    <div className="space-y-6 p-4">
      {/* Tabs */}
      <div className="flex border-b border-gray-200 dark:border-gray-700">
        {tabs.map((tab) => (
          <button
            key={tab.id}
            onClick={() => {
              setActiveTab(tab.id);
              setActiveCard(getDefaultCardForTab(tab.id));
            }}
            className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
              activeTab === tab.id
                ? "border-purple-600 text-purple-600 dark:text-purple-400"
                : "border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:border-gray-300 dark:hover:border-gray-600"
            }`}
          >
            {t(tab.label)}
          </button>
        ))}
      </div>

      {/* Cards */}
      {activeTab === "tag-based-reference" ? (
        <TagBasedReferenceNumbers unitId={unitId} className="w-full" />
      ) : (
        <>
          <div className="flex flex-wrap gap-4">
            {cards.map((card) => (
              <Card
                key={card.id}
                onClick={() => setActiveCard(card.id)}
                className={`inline-flex w-fit min-w-[260px] max-w-full shadow-sm hover:shadow-md transition-shadow cursor-pointer dark:bg-gray-800 dark:border-gray-700 ${
                  activeCard === card.id
                    ? "ring-2 ring-purple-600 dark:ring-purple-400"
                    : ""
                }`}
              >
                <CardHeader className="pb-2 items-center">
                  <CardTitle className="text-sm font-medium text-gray-700 dark:text-gray-200 text-center whitespace-nowrap">
                    {t(card.label)}
                  </CardTitle>
                </CardHeader>
              </Card>
            ))}
          </div>

          <div className="flex justify-end mb-4">
            <Button onClick={() => handleAddClick(activeCard)}>
              <Plus className="h-4 w-4 mr-2" />
              {t("contentManagement.add")}
            </Button>
          </div>

          {/* Table */}
          <PrefixSuffixTable
            items={items}
            isLoading={isLoading}
            onEdit={handleEdit}
            onDelete={handleDelete}
            showPositionColumn={activeTab === "positionPrefix"}
            showCountColumn={
              activeTab === "positionPrefix" || activeTab === "referenceNumber"
            }
            positions={positions}
          />

          {/* Modal */}
          {modalOpen && modalConfig && (
            <PrefixModal
              open={modalOpen}
              onClose={handleModalClose}
              onSuccess={handleModalSuccess}
              unitId={unitId}
              cardType={modalConfig.cardType}
              recordType={modalConfig.recordType}
              editingItem={modalConfig.editingItem}
              positions={positions}
            />
          )}

          <AlertDialog
            open={!!pendingReferenceDelete}
            onOpenChange={(open) => {
              if (!open && !isDeletingReference) {
                setPendingReferenceDelete(null);
              }
            }}
          >
            <AlertDialogContent>
              <AlertDialogHeader>
                <AlertDialogTitle>
                  {t(
                    "prefixes.deleteConfirmTitle",
                    "Delete reference number prefix?",
                  )}
                </AlertDialogTitle>
                <AlertDialogDescription>
                  {t(
                    "prefixes.deleteConfirmDescription",
                    "Are you sure you want to delete this prefix? This action cannot be undone.",
                  )}
                </AlertDialogDescription>
              </AlertDialogHeader>
              <AlertDialogFooter>
                <AlertDialogCancel disabled={isDeletingReference}>
                  {t("common.cancel") || "Cancel"}
                </AlertDialogCancel>
                <AlertDialogAction
                  onClick={confirmReferenceDelete}
                  disabled={isDeletingReference}
                  className="bg-destructive text-white hover:bg-destructive/90"
                >
                  {isDeletingReference
                    ? t("contentManagement.loading", "Loading...")
                    : t("common.delete", "Delete") || "Delete"}
                </AlertDialogAction>
              </AlertDialogFooter>
            </AlertDialogContent>
          </AlertDialog>
        </>
      )}
    </div>
  );
};
