import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useRef, useState } from "react";
import { DialogMode } from "../types/experience.types";
import {
  EducationBody,
  EducationFormValues,
  MappedEducation,
} from "../types/education.types";
import {
  addEducation,
  editEducation,
  deleteEducation,
} from "@/lib/services/profile.service";
import showCustomToast from "@/components/common/toaster/CustomToast";
import { AxiosError } from "axios";
import {
  mapFormToBody,
  mapItemToEducationFormValues,
} from "../utils/education.utils";
import { YearsData } from "@/dummyData/data";

export function useEducationSection() {
  const queryClient = useQueryClient();

  // ─── Dialog state ─────────────────────────────────────────────────────────
  const [isDialogOpen, setIsDialogOpen] = useState(false);
  const [defaultValues, setDefaultValues] = useState<
    EducationFormValues[] | undefined
  >(undefined);

  // ─── Refs ─────────────────────────────────────────────────────────────────
  const modeRef = useRef<DialogMode>("add");
  const editingIdRef = useRef<number | undefined>(undefined);
  const editingUuidRef = useRef<string | undefined>(undefined);

  // ─── Mutation ─────────────────────────────────────────────────────────────
  const { mutate, isPending } = useMutation({
    mutationFn: (body: EducationBody) =>
      modeRef.current === "edit" && editingUuidRef.current
        ? editEducation(editingUuidRef.current, body)
        : addEducation(body),
    onMutate: async (newBody) => {
      await queryClient.cancelQueries({ queryKey: ["profile"] });
      const previousProfile = queryClient.getQueryData(["profile"]);

      queryClient.setQueryData(["profile"], (old: any) => {
        if (!old) return old;
        const educations = [...(old.data.educations || [])];

        if (modeRef.current === "edit" && editingUuidRef.current) {
          const index = educations.findIndex(
            (e: any) => e.uuid === editingUuidRef.current,
          );
          if (index !== -1) {
            educations[index] = { ...educations[index], ...newBody };
          }
        } else {
          // Add optimistic item
          educations.unshift({
            ...newBody,
            uuid: "temp-" + Date.now(),
          });
        }

        return {
          ...old,
          data: { ...old.data, educations },
        };
      });

      return { previousProfile };
    },
    onSuccess: (data: any) => {
      showCustomToast({ type: "success", message: data.message });
      closeDialog();
    },
    onError: (error: AxiosError<{ message: string }>, _, context: any) => {
      queryClient.setQueryData(["profile"], context.previousProfile);
      showCustomToast({
        type: "error",
        message: error.response?.data?.message ?? "Something went wrong",
      });
    },
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ["profile"] });
    },
  });

  const { mutate: deleteMutate } = useMutation({
    mutationFn: deleteEducation,
    onMutate: async (uuid) => {
      await queryClient.cancelQueries({ queryKey: ["profile"] });
      const previousProfile = queryClient.getQueryData(["profile"]);
      queryClient.setQueryData(["profile"], (old: any) => {
        if (!old) return old;
        return {
          ...old,
          data: {
            ...old.data,
            educations: (old.data.educations || []).filter(
              (edu: any) => edu.uuid !== uuid,
            ),
          },
        };
      });
      return { previousProfile };
    },
    onSuccess: () => {
      showCustomToast({ type: "success", message: "Education deleted" });
    },
    onError: (err, uuid, context: any) => {
      queryClient.setQueryData(["profile"], context.previousProfile);
      showCustomToast({ type: "error", message: "Failed to delete education" });
    },
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ["profile"] });
    },
  });

  // ─── Handlers ─────────────────────────────────────────────────────────────
  const openAddDialog = () => {
    modeRef.current = "add";
    editingIdRef.current = undefined;
    editingUuidRef.current = undefined;
    setDefaultValues(undefined);
    setIsDialogOpen(true);
  };

  const openEditDialog = (item: MappedEducation) => {
    modeRef.current = "edit";
    // In education, id is often the database id (number) while uuid is the string id.
    // mapFormToBody needs the id (number) for the body, but optimistic update needs uuid.
    editingIdRef.current = typeof item.id === "number" ? item.id : undefined;
    editingUuidRef.current =
      typeof item.id === "string" ? item.id : (item as any).uuid;

    setDefaultValues([mapItemToEducationFormValues(item)]);
    setIsDialogOpen(true);
  };

  const closeDialog = () => {
    setIsDialogOpen(false);
    setDefaultValues(undefined);
  };

  const handleSubmit = (data: { education: EducationFormValues[] }) => {
    console.log("DDDD----", data);

    const body = mapFormToBody(data.education[0], editingIdRef.current);
    console.log("bodyDDDD----", body);

    mutate(body);
  };

  return {
    isDialogOpen,
    defaultValues,
    isPending,
    isEditing: modeRef.current === "edit",
    openAddDialog,
    openEditDialog,
    closeDialog,
    handleSubmit,
    deleteEducation: deleteMutate,
    yearsOptions: YearsData,
  };
}
