import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
import {
  createNewBooking,
  fetchBookings,
  fetchBookingById,
  updateBookingStatus,
  cancelBooking,
  createBooking,
  getBookings,
  getBookingById
} from "../queries/bookings"
import type { CreateBookingPayload, Booking } from "@/types/bookings"
import { useToaster } from "@/context/ToasterContext"
import { queryClient } from "../client"
import { api } from "@/lib/api"

import { transformAvailabilityToSuggestions } from "@/lib/utils"

export function useCreateBooking() {
  const toast = useToaster()

  return useMutation({
    mutationFn: async (payload: CreateBookingPayload) => {
      const { data } = await api.post("/appointments", payload)
      // Check for slot availability in successful (200 OK) response
      if (data.reason === "SLOT_NOT_AVAILABLE" && data.availability) {
        return {
          ...data,
          suggestions: transformAvailabilityToSuggestions(data.availability),
          message: "The requested slot is not available. Please choose from the following suggestions."
        }
      }

      // If the backend returns success: false in a 200 OK response, throw to trigger onError
      if (data.success === false) {
        throw { response: { data } }
      }

      return data
    },
    onSuccess: (data) => {
      // Check if this is a "time not available" response (already transformed in mutationFn or old format)
      if (data.suggestions) {
        // This is the time not available case - don't invalidate queries or show success
        return data
      }

      // Normal success case
      toast.showSuccess(data?.message || "Booking created successfully!")
      queryClient.invalidateQueries({ queryKey: getBookings })
      return data
    },
    onError: (error: any) => {
      console.error("Booking creation failed:", error)
      const data = error.response?.data
      if (data?.reason === "SLOT_NOT_AVAILABLE" && data?.availability) {
        // The component will handle this via its own onError which will see the same error
        return
      }
      toast.showError(data?.reason || data?.message || "Failed to create booking. Please try again.")
    }
  })
}

export function useGetBookings(page = 1, limit = 10) {
  return useQuery({
    queryKey: [...getBookings, page, limit],
    queryFn: () => fetchBookings(page, limit)
  })
}

export function useGetBookingById(id: string) {
  return useQuery({
    queryKey: getBookingById(id),
    queryFn: () => fetchBookingById(id),
    enabled: !!id
  })
}

export function useUpdateBookingStatus() {
  const toast = useToaster()

  return useMutation({
    mutationFn: async ({ id, status }: { id: string; status: Booking["status"] }) => {
      const { data } = await updateBookingStatus(id, status)
      if (data?.success === false) {
        throw { response: { data } }
      }
      return data
    },
    onSuccess: (data, { status }) => {
      toast.showSuccess(data?.message || `Booking status updated to ${status} successfully!`)
      queryClient.invalidateQueries({ queryKey: getBookings })
      queryClient.invalidateQueries({ queryKey: getBookingById(data._id) })
    },
    onError: (error: any) => {
      console.error("Booking status update failed:", error)
      const data = error.response?.data
      toast.showError(data?.reason || data?.message || "Failed to update booking status. Please try again.")
    }
  })
}

export function useCancelBooking() {
  const toast = useToaster()

  return useMutation({
    mutationFn: async (id: string) => {
      const { data } = await cancelBooking(id)
      if (data?.success === false) {
        throw { response: { data } }
      }
      return data
    },
    onSuccess: (data, id) => {
      toast.showSuccess(data?.message || "Booking cancelled successfully!")
      queryClient.invalidateQueries({ queryKey: getBookings })
      queryClient.invalidateQueries({ queryKey: getBookingById(id) })
    },
    onError: (error: any) => {
      console.error("Booking cancellation failed:", error)
      const data = error.response?.data
      toast.showError(data?.reason || data?.message || "Failed to cancel booking. Please try again.")
    }
  })
}
