import { useQuery } from "@tanstack/react-query";
import {
  PrefixSuffixName,
  PrefixSuffixDto,
  prefixSuffixService,
} from "@/user-management/services/api/prefixSuffixService";

export type ExtendedPrefixSuffixDto = PrefixSuffixDto & {
  type:
    | "prefix"
    | "suffix"
    | "reference"
    | "externalReference"
    | "internalMemoReference";
  isForCC: boolean;
  configId?: string;
  name: PrefixSuffixName | string;
  internalPrefix: PrefixSuffixName | null;
  internalSuffix: PrefixSuffixName | null;
  internalPrefixCC: PrefixSuffixName | null;
  internalSuffixCC: PrefixSuffixName | null;
  referenceNumberPrefix: string | null;
  externalReferenceNumberPrefix: string | null;
  internalMemoReferenceNumberPrefix: string | null;
};

const shouldFetch = (type: string | undefined, expected: string[]) =>
  !type || type === "all" || expected.includes(type);

export const usePrefixSuffix = (
  unitId: string,
  selectedRecordTypeFilter?: string,
  isCCFilter?: boolean,
  skip: number = 0,
  take: number = 10
) => {
  return useQuery({
    queryKey: ["prefixSuffix", unitId, selectedRecordTypeFilter, isCCFilter, skip, take],
    enabled: !!unitId,
    staleTime: 10 * 60 * 1000,
    queryFn: async () => {
      const isRef = selectedRecordTypeFilter === "reference" || selectedRecordTypeFilter === "externalReference";
      const shouldFetchReg = !isCCFilter || isRef;
      const types = [
        "external",
        "internal_memo",
        "branch",
        "non_smart_user",
        "internal",
      ];
      const validType = types.includes(selectedRecordTypeFilter ?? "");
      const typeKey = validType ? selectedRecordTypeFilter ?? "" : "";

      const [
        prefixRes,
        suffixRes,
        ccPrefixRes,
        ccSuffixRes,
        internalConfigRes,
      ] = await Promise.all([
        shouldFetchReg &&
        shouldFetch(selectedRecordTypeFilter, ["prefix", ...types])
          ? prefixSuffixService.getPrefix(unitId, typeKey, skip, take)
          : { data: { items: [], count: 0 } },

        shouldFetchReg &&
        shouldFetch(selectedRecordTypeFilter, ["suffix", ...types])
          ? prefixSuffixService.getSuffix(unitId, typeKey, skip, take)
          : { data: { items: [], count: 0 } },

        isCCFilter &&
        shouldFetch(selectedRecordTypeFilter, ["prefix", ...types])
          ? prefixSuffixService.getPrefixCC(unitId, typeKey, skip, take)
          : { data: { items: [], count: 0 } },

        isCCFilter &&
        shouldFetch(selectedRecordTypeFilter, ["suffix", ...types])
          ? prefixSuffixService.getSuffixCC(unitId, typeKey, skip, take)
          : { data: { items: [], count: 0 } },

        // ✅ also fetch config for "reference"
        [
          "internal_memo",
          "internal",
          "reference",
          "externalReference",
          "internalMemoReference",
        ].includes(selectedRecordTypeFilter ?? "")
          ? prefixSuffixService.getInternalConfig(unitId)
          : { data: {} },
      ]);

      const mapItems = (
        items: PrefixSuffixDto[] = [],
        type: "prefix" | "suffix",
        isForCC = false
      ): ExtendedPrefixSuffixDto[] =>
        items.map((item) => ({
          ...item,
          type,
          isForCC,
          internalPrefix: null,
          internalSuffix: null,
          internalPrefixCC: null,
          internalSuffixCC: null,
          referenceNumberPrefix: null,
          externalReferenceNumberPrefix: null,
          internalMemoReferenceNumberPrefix: null,
          
        }));

      const result: ExtendedPrefixSuffixDto[] = [
        ...mapItems(prefixRes.data.items, "prefix"),
        ...mapItems(suffixRes.data.items, "suffix"),
        ...mapItems(ccPrefixRes.data.items, "prefix", true),
        ...mapItems(ccSuffixRes.data.items, "suffix", true),
      ];

      // ✅ Add internalConfig-based values
      const internalData =
        "items" in internalConfigRes.data
          ? internalConfigRes.data.items?.[0]
          : undefined;
      if (internalData) {
        const internalPrefix = internalData.internalPrefix ?? null;
        const internalSuffix = internalData.internalSuffix ?? null;
        const internalPrefixCC = internalData.internalPrefixCC ?? null;
        const internalSuffixCC = internalData.internalSuffixCC ?? null;
        const referenceNumberPrefix = internalData.referenceNumberPrefix ?? null;
        const externalReferenceNumberPrefix =
          internalData.externalReferenceNumberPrefix ?? null;
        const internalMemoReferenceNumberPrefix =
          internalData.internalMemoReferenceNumberPrefix ?? null;

        if (
          ["internal", "internal_memo"].includes(selectedRecordTypeFilter ?? "")
        ) {
          result.push(
            {
              id: "internalPrefix",
              type: "prefix",
              isForCC: false,
              recordTypeKey: selectedRecordTypeFilter ?? "internal",
              configId: internalData.id,
               name: internalPrefix ?? { am: "", en: "" },
               internalPrefix,
               internalSuffix,
               internalPrefixCC,
               internalSuffixCC,
               referenceNumberPrefix,
               createdAt: "",
               updatedAt: "",
               externalReferenceNumberPrefix,
               internalMemoReferenceNumberPrefix,
             },
             {
               id: "internalSuffix",
               type: "suffix",
               isForCC: false,
               recordTypeKey: selectedRecordTypeFilter ?? "internal",
               configId: internalData.id,
               name: internalSuffix ?? { am: "", en: "" },
               internalPrefix,
               internalSuffix,
               internalPrefixCC,
               internalSuffixCC,
               referenceNumberPrefix,
               createdAt: "",
               updatedAt: "",
               externalReferenceNumberPrefix,
               internalMemoReferenceNumberPrefix,
             },
             {
               id: "internalPrefixCC",
               type: "prefix",
               isForCC: true,
               recordTypeKey: selectedRecordTypeFilter ?? "internal",
               configId: internalData.id,
               name: internalPrefixCC ?? { am: "", en: "" },
               internalPrefix,
               internalSuffix,
               internalPrefixCC,
               internalSuffixCC,
               referenceNumberPrefix,
               createdAt: "",
               updatedAt: "",
               externalReferenceNumberPrefix,
               internalMemoReferenceNumberPrefix,
             },
             {
               id: "internalSuffixCC",
               type: "suffix",
               isForCC: true,
               recordTypeKey: selectedRecordTypeFilter ?? "internal",
               configId: internalData.id,
               name: internalSuffixCC ?? { am: "", en: "" },
               internalPrefix,
               internalSuffix,
               internalPrefixCC,
               internalSuffixCC,
               referenceNumberPrefix,
               createdAt: "",
               updatedAt: "",
               externalReferenceNumberPrefix,
               internalMemoReferenceNumberPrefix,
             }
           );
         }

        // ✅ Always handle "reference" from internal config
        if (selectedRecordTypeFilter === "reference") {
          result.push({
            id: "internalReference",
            type: "reference",
            isForCC: false,
            recordTypeKey: "reference",
            configId: internalData.id,
            name: {
              am: referenceNumberPrefix ?? "",
              en: referenceNumberPrefix ?? "",
            },
            internalPrefix,
            internalSuffix,
            internalPrefixCC,
            internalSuffixCC,
            referenceNumberPrefix,
            createdAt: "",
            updatedAt: "",
            externalReferenceNumberPrefix,
            internalMemoReferenceNumberPrefix,
          });
        }
        // ✅ Always handle "reference" from internal config
        if (selectedRecordTypeFilter === "externalReference") {
          result.push({
            id: "internalReference",
            type: "externalReference",
            isForCC: false,
            recordTypeKey: "reference",
            configId: internalData.id,
            name: {
              am: externalReferenceNumberPrefix ?? "",
              en: externalReferenceNumberPrefix ?? "",
            },
            internalPrefix,
            internalSuffix,
            internalPrefixCC,
            internalSuffixCC,
            referenceNumberPrefix,
            createdAt: "",
            updatedAt: "",
            externalReferenceNumberPrefix,
            internalMemoReferenceNumberPrefix,
          });
        }
         if (selectedRecordTypeFilter === "internalMemoReference") {
           result.push({
             id: "internalReference",
             type: "internalMemoReference",
             isForCC: false,
             recordTypeKey: "reference",
             configId: internalData.id,
             name: {
               am: internalMemoReferenceNumberPrefix ?? "",
               en: internalMemoReferenceNumberPrefix ?? "",
              },
              internalPrefix,
              internalSuffix,
              internalPrefixCC,
              internalSuffixCC,
              referenceNumberPrefix,
              createdAt: "",
              updatedAt: "",
              externalReferenceNumberPrefix,
              internalMemoReferenceNumberPrefix,
            });
          }
      }

      // ✅ Filter logic
      let filtered = isCCFilter
        ? result.filter((item) => item.isForCC)
        : result;

      if (
        ["prefix", "suffix", "reference"].includes(
          selectedRecordTypeFilter ?? ""
        )
      ) {
        filtered = filtered.filter(
          (item) => item.type === selectedRecordTypeFilter
        );
      } else if (validType) {
        filtered = filtered.filter(
          (item) => item.recordTypeKey === selectedRecordTypeFilter
        );
      }

      // Get total count from the first response that has data
      const totalCount = prefixRes.data.count || suffixRes.data.count || ccPrefixRes.data.count || ccSuffixRes.data.count || 0;

      return {
        items: filtered,
        count: totalCount
      };
    },
  });
};
