import { useRef, useState } from "react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
import {
  SkillBody,
  SkillDialogConfig,
  SkillDialogKey,
} from "../types/skills.type";
import { editSkills, deleteSkill } from "@/lib/services/profile.service";
import showCustomToast from "@/components/common/toaster/CustomToast";

// ─── Static dialog config ────────────────────────────────────────────────────
export const SKILL_DIALOG_CONFIG: Record<SkillDialogKey, SkillDialogConfig> = {
  soft: {
    title: "Soft Skills",
    variant: "softSkills",
    formKey: "softSkills",
    nameField: "softSkillName",
  },
  tools: {
    title: "Tools Skills",
    variant: "toolsSkills",
    formKey: "toolsSkills",
    nameField: "toolsSkillName",
  },
  language: {
    title: "Language Skills",
    variant: "languageSkills",
    formKey: "languageSkills",
    nameField: "languageSkillName",
  },
};

interface UseSkillsSectionReturn {
  activeDialog: SkillDialogKey | null;
  dialogKey: string;
  isEditingToggle: (key: SkillDialogKey) => void;
  isEdit: SkillDialogKey | null;
  isPending: boolean;
  openDialog: (key: SkillDialogKey) => void;
  closeDialog: () => void;
  handleSubmit: (data: Record<string, any>) => void;
  deleteSkill: (uuid: string, type: string) => void;
}

export function useSkillsSection(): UseSkillsSectionReturn {
  const queryClient = useQueryClient();

  const [activeDialog, setActiveDialog] = useState<SkillDialogKey | null>(null);
  const [dialogKey, setDialogKey] = useState("");

  const activeDialogRef = useRef<SkillDialogKey | null>(null);
  const activeEditRef = useRef<SkillDialogKey | null>(null);

  // ─── Add/Update Mutation ───────────────────────────────────────────────────
  const { mutate, isPending } = useMutation<
    any,
    AxiosError<{ message: string }>,
    { uuids: string[]; type: string; items: any[] }
  >({
    mutationFn: (data) => editSkills({ type: data.type, uuids: data.uuids }),
    onMutate: async ({ type, items }) => {
      await queryClient.cancelQueries({ queryKey: ["profile"] });
      const previousProfile = queryClient.getQueryData(["profile"]);

      queryClient.setQueryData(["profile"], (old: any) => {
        if (!old) return old;
        const skills = { ...old.data.skills };
        const typeKey = type as "soft" | "tool" | "language";

        const currentSkills = [...(skills[typeKey] || [])];
        items.forEach((newItem) => {
          const itemUuid = newItem.uuid || newItem.id;
          if (!currentSkills.find((s) => s.uuid === itemUuid)) {
            currentSkills.push({
              id: newItem.id,
              uuid: itemUuid,
              name: newItem.name || newItem.label,
              label: newItem.name || newItem.label,
              type: typeKey,
            });
          }
        });

        return {
          ...old,
          data: {
            ...old.data,
            skills: { ...skills, [typeKey]: currentSkills },
          },
        };
      });

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

  // ─── Delete Mutation ───────────────────────────────────────────────────────
  const { mutate: deleteMutate } = useMutation({
    mutationFn: (args: { uuid: string; type: string; uuids: string[] }) =>
      editSkills({ type: args.type, uuids: args.uuids }),
    onMutate: async ({ uuid, type }) => {
      await queryClient.cancelQueries({ queryKey: ["profile"] });
      const previousProfile = queryClient.getQueryData(["profile"]);

      queryClient.setQueryData(["profile"], (old: any) => {
        if (!old) return old;
        const skills = { ...old.data.skills };
        const typeKey = type as "soft" | "tool" | "language";

        const currentSkills = (skills[typeKey] || []).filter(
          (s: any) => s.uuid !== uuid,
        );

        return {
          ...old,
          data: {
            ...old.data,
            skills: { ...skills, [typeKey]: currentSkills },
          },
        };
      });

      return { previousProfile };
    },
    onSuccess: () => {
      showCustomToast({ type: "success", message: "Skill removed" });
    },
    onError: (err, variables, context: any) => {
      queryClient.setQueryData(["profile"], context.previousProfile);
      showCustomToast({ type: "error", message: "Failed to remove skill" });
    },
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ["profile"] });
      queryClient.invalidateQueries({ queryKey: ["skills"] });
    },
  });

  const openDialog = (key: SkillDialogKey) => {
    activeDialogRef.current = key;
    setActiveDialog(key);
    setDialogKey(`${key}-${Date.now()}`);
  };

  const closeDialog = () => {
    setActiveDialog(null);
    activeDialogRef.current = null;
  };

  const handleSubmit = (data: Record<string, any>) => {
    const key = activeDialogRef.current;
    if (!key) return;

    const config = SKILL_DIALOG_CONFIG[key];
    const items = data[config.formKey];
    if (!items || !items.length) return;

    const typeKey = key === "tools" ? "tool" : key;

    const newUuids = items
      .flatMap((row: any) => row[config.nameField] ?? [])
      .filter(Boolean);

    const newItems = newUuids.map((uuid: string) => ({
      uuid,
      id: uuid,
      name: "Loading...",
      label: "Loading...",
    }));

    mutate({
      uuids: newUuids,
      type: typeKey,
      items: newItems,
    });
  };

  const handleDeleteSkill = (uuid: string, type: string) => {
    const currentProfile = queryClient.getQueryData(["profile"]) as any;
    const currentSkills = currentProfile?.data?.skills?.[type] || [];
    const remainingUuids = currentSkills
      .map((s: any) => s.uuid)
      .filter((id: string) => id !== uuid);

    deleteMutate({ uuid, type, uuids: remainingUuids });
  };

  const [isEdit, setIsEdit] = useState<SkillDialogKey | null>(null);

  const isEditingToggle = (key: SkillDialogKey) => {
    activeEditRef.current = key;
    setIsEdit((prev) => (prev === key ? null : key));
  };

  return {
    activeDialog,
    dialogKey,
    isEditingToggle,
    isEdit,
    isPending,
    openDialog,
    closeDialog,
    handleSubmit,
    deleteSkill: handleDeleteSkill,
  };
}
