import { root } from '@repo/core'
import {
  type CheckFavoritedInput,
  type CheckFavoritedResponse,
  type FavoriteTemplateInput,
  TemplateSocialController,
  type UnfavoriteTemplateInput,
} from '@repo/sdk'
import { useCallback, useState } from 'react'

import { type ApiError } from '@/lib/types'

import { handleError } from './use-error'

export const useTemplateFavorite = (
  templateId?: string,
  initialFavorited = false,
) => {
  const [favorited, setFavorited] = useState<boolean>(initialFavorited)
  const [loading, setLoading] = useState<boolean>(false)
  const [error, setError] = useState<ApiError | null>(null)

  const favorite = useCallback(async () => {
    if (!templateId) {
      return { data: null, error: null }
    }

    setLoading(true)
    setError(null)

    const controller = root.get(TemplateSocialController)
    const params: FavoriteTemplateInput = {
      templateId,
    }

    const { data, error } = await handleError(
      async () => await controller.favorite(params),
    )

    if (error) {
      setError(error)
      setLoading(false)
      return { data: null, error }
    }

    setFavorited(true)
    setLoading(false)
    return { data, error: null }
  }, [templateId])

  const unfavorite = useCallback(async () => {
    if (!templateId) {
      return { data: null, error: null }
    }

    setLoading(true)
    setError(null)

    const controller = root.get(TemplateSocialController)
    const params: UnfavoriteTemplateInput = {
      templateId,
    }

    const { data, error } = await handleError(
      async () => await controller.unfavorite(params),
    )

    if (error) {
      setError(error)
      setLoading(false)
      return { data: null, error }
    }

    setFavorited(false)
    setLoading(false)
    return { data, error: null }
  }, [templateId])

  const checkFavorited = useCallback(async () => {
    if (!templateId) {
      return { data: null, error: null }
    }

    setLoading(true)
    setError(null)

    const controller = root.get(TemplateSocialController)
    const params: CheckFavoritedInput = {
      templateId,
    }

    const { data, error } = await handleError(
      async () => await controller.checkFavorited(params),
    )

    if (error) {
      setError(error)
      setLoading(false)
      return { data: null, error }
    }

    setFavorited(data.favorited)
    setLoading(false)
    return { data, error: null }
  }, [templateId])

  return {
    favorited,
    loading,
    error,
    favorite,
    unfavorite,
    checkFavorited,
  }
}
