import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "@xtablo/shared";
import type { TabloFolder, TabloFoldersMetadata } from "@xtablo/shared-types";
import { useAuthedApi } from "./auth";

// Re-export types for convenience
export type { TabloFolder, TabloFoldersMetadata } from "@xtablo/shared-types";

const toastOptions = { timeout: 5000 };

// Hook to get folders for a tablo
export function useTabloFolders(tabloId: string) {
  const api = useAuthedApi();

  return useQuery<TabloFoldersMetadata>({
    queryKey: ["tablo-folders", tabloId],
    queryFn: async () => {
      const response = await api.get(`/api/v1/tablo-data/${tabloId}/folders`);
      if (response.status === 200) {
        return response.data;
      }
      return { folders: [], version: 1 };
    },
    enabled: !!tabloId,
  });
}

// Hook to create a new folder
export function useCreateTabloFolder() {
  const api = useAuthedApi();
  const queryClient = useQueryClient();

  return useMutation<
    TabloFolder,
    Error,
    { tabloId: string; name: string; description?: string; createdBy: string }
  >({
    mutationFn: async ({ tabloId, name, description }) => {
      const response = await api.post(`/api/v1/tablo-data/${tabloId}/folders`, {
        name,
        description,
      });

      if (response.status !== 200) {
        throw new Error(response.data?.error || "Failed to create folder");
      }

      return response.data.folder;
    },
    onSuccess: (folder) => {
      toast.add(
        {
          title: "Livrable créé",
          description: `Le livrable "${folder.name}" a été créé avec succès`,
          type: "success",
        },
        toastOptions
      );
    },
    onError: (error) => {
      toast.add(
        {
          title: "Erreur",
          description: `Échec de la création du livrable: ${error.message}`,
          type: "error",
        },
        toastOptions
      );
    },
    onSettled: (_, _err, variables) => {
      if (variables) {
        queryClient.invalidateQueries({
          queryKey: ["tablo-folders", variables.tabloId],
        });
      }
    },
  });
}

// Hook to update a folder
export function useUpdateTabloFolder() {
  const api = useAuthedApi();
  const queryClient = useQueryClient();

  return useMutation<
    TabloFolder,
    Error,
    { tabloId: string; folderId: string; name?: string; description?: string }
  >({
    mutationFn: async ({ tabloId, folderId, name, description }) => {
      const response = await api.put(`/api/v1/tablo-data/${tabloId}/folders/${folderId}`, {
        name,
        description,
      });

      if (response.status !== 200) {
        throw new Error(response.data?.error || "Failed to update folder");
      }

      return response.data.folder;
    },
    onSuccess: (folder) => {
      toast.add(
        {
          title: "Livrable mis à jour",
          description: `Le livrable "${folder.name}" a été mis à jour`,
          type: "success",
        },
        toastOptions
      );
    },
    onError: (error) => {
      toast.add(
        {
          title: "Erreur",
          description: `Échec de la mise à jour du livrable: ${error.message}`,
          type: "error",
        },
        toastOptions
      );
    },
    onSettled: (_, _err, variables) => {
      if (variables) {
        queryClient.invalidateQueries({
          queryKey: ["tablo-folders", variables.tabloId],
        });
      }
    },
  });
}

// Hook to delete a folder
export function useDeleteTabloFolder() {
  const api = useAuthedApi();
  const queryClient = useQueryClient();

  return useMutation<void, Error, { tabloId: string; folderId: string; folderName: string }>({
    mutationFn: async ({ tabloId, folderId }) => {
      const response = await api.delete(`/api/v1/tablo-data/${tabloId}/folders/${folderId}`);

      if (response.status !== 200) {
        throw new Error(response.data?.error || "Failed to delete folder");
      }
    },
    onSuccess: (_, variables) => {
      toast.add(
        {
          title: "Livrable supprimé",
          description: `Le livrable "${variables.folderName}" a été supprimé`,
          type: "success",
        },
        toastOptions
      );
    },
    onError: (error) => {
      toast.add(
        {
          title: "Erreur",
          description: `Échec de la suppression du livrable: ${error.message}`,
          type: "error",
        },
        toastOptions
      );
    },
    onSettled: (_, _err, variables) => {
      if (variables) {
        queryClient.invalidateQueries({
          queryKey: ["tablo-folders", variables.tabloId],
        });
      }
    },
  });
}

// Helper function to get folder path prefix for a file
export const getFolderFilePrefix = (folderId: string) => `${folderId}/`;

// Helper to extract folder ID from a file name
export const extractFolderIdFromFileName = (fileName: string): string | null => {
  const match = fileName.match(/^(folder-[^/]+)\//);
  return match ? match[1] : null;
};

// Helper to get the actual file name without folder prefix
export const getFileNameWithoutFolder = (fileName: string): string => {
  const folderId = extractFolderIdFromFileName(fileName);
  if (folderId) {
    return fileName.substring(folderId.length + 1);
  }
  return fileName;
};
