import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "@xtablo/shared";
import { Database } from "@xtablo/shared/types/database.types";
import { RemoveNullFromObject } from "@xtablo/shared/types/removeNull";
import { CreateTablo } from "@xtablo/shared/types/tablos.types";
import { supabase } from "../lib/supabase";
import { useUser } from "../providers/UserStoreProvider";
import { useAuthedApi } from "./auth";

type Tablo = Database["public"]["Tables"]["tablos"];

type TabloUpdate = Tablo["Update"];

type UserTablo = RemoveNullFromObject<Database["public"]["Views"]["user_tablos"]["Row"]>;

// Fetch all tablos
export const useTablosList = () => {
  const user = useUser();
  return useQuery({
    queryKey: ["tablos"],
    queryFn: async () => {
      const { data, error } = await supabase.from("user_tablos").select("*").eq("user_id", user.id);
      if (error) throw error;
      const tablos = data as UserTablo[];
      return tablos;
    },
  });
};

// Fetch single tablo
export const useTablo = (id: string) => {
  const user = useUser();
  return useQuery({
    queryKey: ["tablos", id],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("user_tablos")
        .select("*")
        .eq("id", id)
        .eq("user_id", user.id)
        .single();
      if (error) throw error;
      return data as UserTablo;
    },
  });
};

export const useTabloOverviewLayout = (tabloId: string | undefined) => {
  return useQuery({
    queryKey: ["tablo-overview-layout", tabloId],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("tablos")
        .select("layout_overview_v1")
        .eq("id", tabloId)
        .single();
      if (error) throw error;
      return data.layout_overview_v1;
    },
    enabled: !!tabloId,
  });
};

// Fetch tablo members
export const useTabloMembers = (tabloId: string) => {
  const api = useAuthedApi();
  const { data, isLoading, error } = useQuery({
    queryKey: ["tablo-members", tabloId],
    queryFn: async () => {
      const { data } = await api.get<{
        members: {
          id: string;
          name: string;
          is_admin: boolean;
          email: string;
          avatar_url: string | null;
        }[];
      }>(`/api/v1/tablos/members/${tabloId}`);
      return data.members;
    },
  });

  return { data, isLoading, error };
};

// Create new tablo
export const useCreateTablo = () => {
  const api = useAuthedApi();
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (tablo: CreateTablo) => {
      const { data } = await api.post("/api/v1/tablos/create", tablo);
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["tablos"] });
    },
    onError: (error) => {
      console.error(error);
      toast.add(
        {
          title: "Échec de la création du tablo",
          description: "Veuillez réessayer",
          type: "error",
        },
        {
          timeout: 5000,
        }
      );
    },
  });
};

// Update tablo
export const useUpdateTablo = () => {
  const queryClient = useQueryClient();
  const api = useAuthedApi();

  return useMutation({
    mutationFn: async ({ id, ...tablo }: TabloUpdate & { id: string }) => {
      const { data } = await api.patch(`/api/v1/tablos/update`, {
        id,
        ...tablo,
      });
      return data;
    },
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: ["tablos"] });
      queryClient.invalidateQueries({ queryKey: ["tablos", id] });
      queryClient.invalidateQueries({ queryKey: ["tablo-overview-layout", id] });
      queryClient.invalidateQueries({ queryKey: ["events", "all"] });
      queryClient.invalidateQueries({ queryKey: ["events", id] });
    },
    onError: (error) => {
      console.error(error);
      toast.add(
        {
          title: "Échec de la création du tablo",
          description: "Veuillez réessayer",
          type: "error",
        },
        {
          timeout: 5000,
        }
      );
    },
  });
};

// Delete tablo (soft delete)
export const useDeleteTablo = () => {
  const queryClient = useQueryClient();
  const api = useAuthedApi();

  return useMutation({
    mutationFn: async (id: string) => {
      await api.delete(`/api/v1/tablos/delete`, { data: { id } });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["tablos"] });
    },
    onError: (error) => {
      console.error(error);
      toast.add(
        {
          title: "Échec de la suppression du tablo",
          description: "Veuillez réessayer",
          type: "error",
        },
        {
          timeout: 5000,
        }
      );
    },
  });
};

export const useGetAllTabloAccess = () => {
  const user = useUser();
  const { data, isLoading, error } = useQuery({
    queryKey: ["tablo-access", user.id],
    queryFn: async () => {
      const { data } = await supabase.from("tablo_access").select("*").eq("user_id", user.id);
      return data;
    },
  });
  return { data, isLoading, error };
};

export const useCanCreateTablo = () => {
  const api = useAuthedApi();

  const { data } = useQuery<{ canCreate: boolean }>({
    queryKey: ["can-create-tablo"],
    queryFn: async () => {
      try {
        const { data } = await api.get<{ canCreate: boolean }>("/api/v1/tablos/can-create-tablo");

        return data;
      } catch {
        return { canCreate: false };
      }
    },
  });

  return data?.canCreate;
};
