// PrefixModal.tsx
import React, { useState, useEffect } from "react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@/shared/common/ui/dialog";
import { Button } from "@/shared/common/ui/button";
import { Input } from "@/shared/common/ui/input";
import { Label } from "@radix-ui/react-label";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import {
  CreatePrefixPayload,
  CreateSuffixPayload,
  prefixSuffixService,
} from "@/user-management/services/api/prefixSuffixService";
import { t } from "i18next";
import { PrefixTabType } from "./PrefixAndSuffixCard";
import { toast } from "sonner";
import {
  useAddReferenceNumber,
  useGetReferenceNumbers,
  useUpdateExternalReferencePrefix,
  useUpdateInternalMemoReferencePrefix,
} from "@/shared/hooks/useReferenceNumberPrefixes";
import { useErrorHandler } from "@/shared/hooks/useErrorHandler";
import { SingleSelect } from "@/shared/common/ui/single-select";

interface PrefixModalProps {
  open: boolean;
  onClose: () => void;
  onSuccess: () => void;
  unitId: string;
  cardType: string; // e.g., "prefix", "suffix", "prefixCC", "reference", "internalPrefix", etc.
  recordType: PrefixTabType;
  editingItem?: any;
  positions?: any[];
}

export const PrefixModal = ({
  open,
  onClose,
  onSuccess,
  unitId,
  cardType,
  recordType,
  editingItem,
  positions = [],
}: PrefixModalProps) => {
  const queryClient = useQueryClient();
  const isEditing = !!editingItem;

  // Form state
  const [nameAm, setNameAm] = useState("");
  const [nameEn, setNameEn] = useState("");
  const [positionId, setPositionId] = useState("");

  // Determine if this is a reference type
  const isReference = [
    "reference",
    "externalReference",
    "internalMemoReference",
  ].includes(cardType);
  const isPositionPrefix = recordType === "positionPrefix";
  const isCC = cardType.includes("CC");
  const isReferenceCard = cardType === "reference";
  const isExternalReferenceCard = cardType === "externalReference";
  const isInternalMemoReferenceCard = cardType === "internalMemoReference";
  const positionOptions = positions
    .filter((pos) => Boolean(pos?.id))
    .map((pos) => ({
      value: pos.id,
      label: pos.name?.en || pos.name?.am || pos.id,
    }));
  const positionRecordTypeKey =
    cardType === "internalPrefix"
      ? "internal"
      : cardType === "externalPrefix"
        ? "external"
        : cardType === "internalMemoPrefix"
          ? "internal_memo"
          : editingItem?.recordTypeKey;

  const { data: referenceNumbersData } = useGetReferenceNumbers(
    isReference ? unitId : "",
  );
  const addReferenceNumberMutation = useAddReferenceNumber();
  const updateInternalMemoReferenceMutation =
    useUpdateInternalMemoReferencePrefix();
  const updateExternalReferenceMutation = useUpdateExternalReferencePrefix();
  const { handleError } = useErrorHandler(t);

  const referenceNumbers =
    ((referenceNumbersData?.data as any)?.items?.[0] as any) ||
    referenceNumbersData?.data ||
    {};

  const isArray = Array.isArray(referenceNumbers);
  const referenceNumberPrefix =
    isArray &&
    referenceNumbers?.find((rn: any) => rn.name === "referenceNumberPrefix");

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

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

  // Populate form when editing
  useEffect(() => {
    if (editingItem) {
      if (isReference) {
        setNameAm(editingItem.name?.am || "");
        setNameEn(editingItem.name?.en || "");
      } else {
        setNameAm(editingItem.name?.am || "");
        setNameEn(editingItem.name?.en || "");
      }
      setPositionId(editingItem.positionId || "");
    } else {
      // Reset
      setNameAm("");
      setNameEn("");
      setPositionId("");
    }
  }, [editingItem, isReference]);

  useEffect(() => {
    if (!isReference || editingItem) return;

    if (isReferenceCard) {
      setNameAm(referenceNumbers.referenceNumberPrefix || "");
      setNameEn(referenceNumbers.referenceNumberPrefix || "");
      return;
    }
    if (isExternalReferenceCard) {
      setNameAm(referenceNumbers.externalReferenceNumberPrefix || "");
      setNameEn(referenceNumbers.externalReferenceNumberPrefix || "");

      return;
    }
    if (isInternalMemoReferenceCard) {
      setNameAm(referenceNumbers.internalMemoReferenceNumberPrefix || "");
      setNameEn(referenceNumbers.internalMemoReferenceNumberPrefix || "");
    }
  }, [
    editingItem,
    isReference,
    isReferenceCard,
    isExternalReferenceCard,
    isInternalMemoReferenceCard,
    referenceNumbers.referenceNumberPrefix,
    referenceNumbers.externalReferenceNumberPrefix,
    referenceNumbers.internalMemoReferenceNumberPrefix,
  ]);

  // Mutation for saving
  const { mutate: save, isPending } = useMutation({
    mutationFn: async () => {
      const baseRecordTypeKey = recordType;
      const isPrefixOperation =
        isReference ||
        isPositionPrefix ||
        cardType === "prefix" ||
        cardType === "prefixCC" ||
        cardType === "internalPrefix" ||
        cardType === "externalPrefix" ||
        cardType === "internalMemoPrefix";

      let prefixPayload: CreatePrefixPayload | undefined;
      let suffixPayload: CreateSuffixPayload | undefined;

      if (isReference) {
        if (isReferenceCard) {
          await addReferenceNumberMutation.mutateAsync({
            unitId,
            payload: {
              referenceNumberPrefix: {
                am: nameAm,
                en: nameEn,
              },
            },
          });
          return;
        }

        if (isExternalReferenceCard) {
          await updateExternalReferenceMutation.mutateAsync({
            unitId,
            payload: {
              externalReferenceNumberPrefix: {
                am: nameAm,
                en: nameEn,
              },
            },
          });
          return;
        }

        if (isInternalMemoReferenceCard) {
          await updateInternalMemoReferenceMutation.mutateAsync({
            unitId,
            payload: {
              internalMemoReferenceNumberPrefix: {
                am: nameAm,
                en: nameEn,
              },
            },
          });
          return;
        }
      } else if (isPositionPrefix) {
        if (
          positionRecordTypeKey !== "internal" &&
          positionRecordTypeKey !== "external" &&
          positionRecordTypeKey !== "internal_memo"
        ) {
          throw new Error(
            "Position prefix requires internal, external, or internal_memo recordTypeKey",
          );
        }

        prefixPayload = {
          unitId,
          recordTypeKey: positionRecordTypeKey,
          isForCC: false,
          positionId,
          name: { am: nameAm, en: nameEn },
        };
      } else {
        const commonPayload = {
          unitId,
          recordTypeKey: baseRecordTypeKey,
          isForCC: isCC,
          name: { am: nameAm, en: nameEn },
        };

        if (cardType === "suffix" || cardType === "suffixCC") {
          suffixPayload = commonPayload;
        } else {
          prefixPayload = commonPayload;
        }
      }

      if (isEditing) {
        if (isPrefixOperation && prefixPayload) {
          return prefixSuffixService.editPrefix(editingItem.id, prefixPayload);
        }
        if (suffixPayload) {
          return prefixSuffixService.editSuffix(editingItem.id, suffixPayload);
        }
        throw new Error("Invalid prefix/suffix payload for update");
      }

      if (isPrefixOperation && prefixPayload) {
        return prefixSuffixService.createPrefix(prefixPayload);
      }
      if (suffixPayload) {
        return prefixSuffixService.createSuffix(suffixPayload);
      }
      throw new Error("Invalid prefix/suffix payload for create");
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["prefixSuffix"] });
      toast.success(t("msg.successfullyCompleted"));
      onSuccess();
    },
    onError: (error) => {
      handleError(error);
    },
  });

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    save();
  };

  const isValid = () => {
    if (isReference) return nameAm.trim() !== "" && nameEn.trim() !== "";

    if (isPositionPrefix)
      return nameAm.trim() !== "" && nameEn.trim() !== "" && positionId;
    return nameAm.trim() !== "" && nameEn.trim() !== "";
  };

  return (
    <Dialog open={open} onOpenChange={onClose}>
      <DialogContent className="sm:max-w-[500px] dark:bg-gray-800">
        <DialogHeader>
          <DialogTitle className="dark:text-white">
            {isEditing
              ? t("contentManagement.edit")
              : t("contentManagement.add")}{" "}
            {t(`contentManagement.${cardType}`)}
          </DialogTitle>
        </DialogHeader>
        <form onSubmit={handleSubmit} className="space-y-4">
          {isReference ? (
            <div className="space-y-2">
              <div className="space-y-2">
                <Label htmlFor="nameAm" className="dark:text-gray-200">
                  {t("contentManagement.amharicName")} *
                </Label>
                <Input
                  id="nameAm"
                  value={nameAm}
                  onChange={(e) => setNameAm(e.target.value)}
                  placeholder={t("contentManagement.amharicName")}
                  disabled={isPending}
                  className="dark:bg-gray-700 dark:border-gray-600 dark:text-white"
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="nameEn" className="dark:text-gray-200">
                  {t("contentManagement.englishName")} *
                </Label>
                <Input
                  id="nameEn"
                  value={nameEn}
                  onChange={(e) => setNameEn(e.target.value)}
                  placeholder={t("contentManagement.englishName")}
                  disabled={isPending}
                  className="dark:bg-gray-700 dark:border-gray-600 dark:text-white"
                />
              </div>
            </div>
          ) : (
            <>
              <div className="space-y-2">
                <Label htmlFor="nameAm" className="dark:text-gray-200">
                  {t("contentManagement.amharicName")} *
                </Label>
                <Input
                  id="nameAm"
                  value={nameAm}
                  onChange={(e) => setNameAm(e.target.value)}
                  placeholder={t("contentManagement.amharicName")}
                  disabled={isPending}
                  className="dark:bg-gray-700 dark:border-gray-600 dark:text-white"
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="nameEn" className="dark:text-gray-200">
                  {t("contentManagement.englishName")} *
                </Label>
                <Input
                  id="nameEn"
                  value={nameEn}
                  onChange={(e) => setNameEn(e.target.value)}
                  placeholder={t("contentManagement.englishName")}
                  disabled={isPending}
                  className="dark:bg-gray-700 dark:border-gray-600 dark:text-white"
                />
              </div>
            </>
          )}

          {isPositionPrefix && (
            <div className="space-y-2">
              <Label htmlFor="position" className="dark:text-gray-200">
                {t("contentManagement.position")} *
              </Label>
              <SingleSelect
                options={positionOptions}
                value={positionId}
                onValueChange={setPositionId}
                placeholder={t("contentManagement.selectPosition")}
                className={isPending ? "pointer-events-none opacity-60" : ""}
              />
            </div>
          )}

          <div className="flex justify-end gap-2 pt-4">
            <Button
              type="button"
              variant="outline"
              onClick={onClose}
              disabled={isPending}
            >
              {t("common.Cancel")}
            </Button>
            <Button
              type="submit"
              disabled={!isValid() || isPending}
              className="bg-purple-600 hover:bg-purple-700"
            >
              {isPending
                ? t("contentManagement.saving")
                : (isReferenceCard &&
                      (referenceNumbers.referenceNumberPrefix ||
                        referenceNumbers.externalReferenceNumberPrefix ||
                        referenceNumbers.internalMemoReferenceNumberPrefix)) ||
                    isEditing
                  ? t("common.update")
                  : t("common.save")}
            </Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
};
