import { useMutation, useQuery } from "@tanstack/react-query";
import { queryClient } from "@xtablo/shared";
import { Database } from "@xtablo/shared/types/database.types";
import { useMemo } from "react";
import { useUser } from "src/providers/UserStoreProvider";
import { supabase } from "../lib/supabase";

export type EventTypeData = {
  id: string;
  standardName?: string;
};

export type EventTypeConfig = {
  name: string;
  description: string;
  duration: number; // in minutes
  bufferTime?: number; // buffer time before/after in minutes
  maxBookingsPerDay?: number;
  requiresApproval: boolean;
  price?: number; // optional price
  location?: string; // optional location
  minAdvanceBooking?: {
    value: number;
    unit: "minutes" | "hours" | "days";
  }; // minimum hours in advance
};

export type EventType = EventTypeConfig & {
  id: string;
  standardName?: string;
  isActive: boolean;
};

export type EventTypePayload = {
  name: string;
  description: string;
  duration: number; // in minutes
  bufferTime?: number; // buffer time before/after in minutes
  maxBookingsPerDay?: number;
  requiresApproval: boolean;
  price?: number; // optional price
  location?: string; // optional location
  minAdvanceBooking?: {
    value: number;
    unit: "minutes" | "hours" | "days";
  }; // minimum hours in advance
};

const QUERY_KEY = ["event-types"];

export function useEventTypes() {
  const user = useUser();

  const { data: eventTypesData, isLoading } = useQuery<
    Database["public"]["Tables"]["event_types"]["Row"][]
  >({
    queryKey: QUERY_KEY,
    queryFn: async () => {
      const { data, error } = await supabase
        .from("event_types")
        .select("*")
        .eq("user_id", user.id)
        .is("deleted_at", null);
      if (error) throw error;
      return data;
    },
    enabled: !!user.id,
  });

  const { mutate: addEventType } = useMutation<
    void,
    Error,
    {
      eventType: EventTypePayload;
    }
  >({
    mutationFn: async ({ eventType }: { eventType: EventTypePayload }) => {
      const { error } = await supabase.from("event_types").insert({
        config: eventType,
        is_active: true,
        user_id: user.id,
      });
      if (error) throw error;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: QUERY_KEY });
    },
  });

  const { mutate: updateEventType } = useMutation<
    void,
    Error,
    {
      id: string;
      eventType: EventTypePayload;
    }
  >({
    mutationFn: async ({ id, eventType }: { id: string; eventType: EventTypePayload }) => {
      const { error } = await supabase
        .from("event_types")
        .update({
          config: eventType,
        })
        .eq("id", id);
      if (error) throw error;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: QUERY_KEY });
    },
  });

  const { mutate: toggleEventType } = useMutation<
    void,
    Error,
    {
      id: string;
      isActive: boolean;
    }
  >({
    mutationFn: async ({ id, isActive }: { id: string; isActive: boolean }) => {
      const { error } = await supabase
        .from("event_types")
        .update({
          is_active: isActive,
        })
        .eq("id", id);
      if (error) throw error;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: QUERY_KEY });
    },
  });

  const { mutate: deleteEventType } = useMutation<
    void,
    Error,
    {
      id: string;
    }
  >({
    mutationFn: async ({ id }: { id: string }) => {
      const { error } = await supabase
        .from("event_types")
        .update({ deleted_at: new Date().toISOString() })
        .eq("id", id);
      if (error) throw error;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: QUERY_KEY });
    },
  });

  const eventTypes = useMemo(() => {
    return (
      eventTypesData?.map((eventType) => {
        const eventTypeConfig = eventType.config as EventTypeConfig;
        return {
          ...eventTypeConfig,
          isActive: eventType.is_active,
          id: eventType.id,
          standardName: eventType.standard_name,
        };
      }) ?? []
    );
  }, [eventTypesData]);

  return {
    isLoading,
    eventTypes: eventTypes as EventType[],
    addEventType,
    updateEventType,
    toggleEventType,
    deleteEventType,
  };
}
