import { likeStatus, unlikeStatus } from 'src/lib/api'
import type { Status } from 'src/lib/api-types'
import { queryKeys } from 'src/lib/queries/keys'
import { emit } from 'src/lib/tapestry/emit'
import { postScopeKeys, useCacheMutation } from './cacheMutation'
import { updatePostInCache } from './updatePostInCache'

type LikeMutateType = {
  type: 'like' | 'unlike'
  id: string
  profileId?: string
}

export function useLikeMutation({
  onSuccess,
  profileId,
}: {
  onSuccess?: (data: any, variables: LikeMutateType) => void
  profileId?: string
} = {}) {
  const profileKey = (vars: LikeMutateType) => {
    const uid = vars.profileId ?? profileId
    return uid ? [queryKeys.posts.byUser(uid)] : []
  }

  const { mutate, isPending } = useCacheMutation<Status, LikeMutateType>({
    mutationFn: (vars) => (vars.type === 'like' ? likeStatus(vars) : unlikeStatus(vars)),

    snapshotKeys: (vars) => postScopeKeys(vars.id, profileKey(vars)),

    applyOptimistic: (qc, vars) => {
      const isLike = vars.type === 'like'
      updatePostInCache(
        qc,
        vars.id,
        (post) => ({
          ...post,
          favourited: isLike,
          favourites_count: isLike
            ? (post.favourites_count ?? 0) + 1
            : Math.max(0, (post.favourites_count ?? 1) - 1),
        }),
        profileKey(vars)
      )
    },

    reconcile: (qc, data, vars) => {
      updatePostInCache(qc, data.id, () => data, profileKey(vars))
    },

    onSuccess: (data, vars) => {
      emit(vars.type === 'like' ? 'L' : 'u')
      onSuccess?.(data, vars)
    },
  })

  const handleLike = async (id: string, liked: boolean, statusProfileId?: string) => {
    try {
      await mutate({
        type: liked ? 'like' : 'unlike',
        id,
        profileId: statusProfileId !== undefined ? statusProfileId : profileId,
      })
    } catch (_error) {}
  }

  return { handleLike, isLikePending: isPending }
}
