import { useMutation, useQueryClient } from '@tanstack/react-query'
import { useCallback } from 'react'
import { useConfirmDialog } from 'src/hooks/useConfirmDialog'
import { deleteStatus, likeStatus, unlikeStatus } from 'src/lib/api'
import type { Status } from 'src/lib/api-types'
import { postQueries } from 'src/lib/queries/posts'

// Per-row mutations + helpers for the thread on `/post/[id]`. The composer
// half (text, target, scope, CW, post-mutation, keyboard tracking) was
// removed when the sticky composer was deleted in favour of the modal
// `PostComposer` on `/camera?inReplyToId=...`. Replies are posted by the
// modal's own `useComposer.handlePost`; the optimistic cache update lands
// via `appendReplyToCachedThread` from there. The hook now owns *only*
// what the screen still uses on every row: like and delete.

type Params = {
  statusId: string
}

export function useThreadActions({ statusId }: Params) {
  const queryClient = useQueryClient()
  const { confirm, dialog: confirmDialog } = useConfirmDialog()

  const threadKey = postQueries.thread(statusId).queryKey

  type Ctx = { ancestors: Status[]; descendants: Status[] }

  const updateRowInThread = useCallback(
    (id: string, patch: Partial<Status>) => {
      queryClient.setQueryData<Ctx | undefined>(threadKey, (old) => {
        if (!old) return old
        const map = (s: Status) => (s.id === id ? ({ ...s, ...patch } as Status) : s)
        return {
          ancestors: old.ancestors.map(map),
          descendants: old.descendants.map(map),
        }
      })
    },
    [queryClient, threadKey]
  )

  const removeRowFromThread = useCallback(
    (id: string) => {
      queryClient.setQueryData<Ctx | undefined>(threadKey, (old) => {
        if (!old) return old
        return {
          ancestors: old.ancestors.filter((s) => s.id !== id),
          descendants: old.descendants.filter((s) => s.id !== id),
        }
      })
    },
    [queryClient, threadKey]
  )

  const likeMutation = useMutation({
    mutationFn: async (input: { id: string; favourited: boolean }) => {
      const res = input.favourited
        ? await unlikeStatus({ id: input.id })
        : await likeStatus({ id: input.id })
      return { id: input.id, patch: res as Partial<Status> }
    },
    onSuccess: ({ id, patch }) => {
      const fields: Partial<Status> = {
        favourited: patch.favourited,
        favourites_count: patch.favourites_count,
        liked_by: (patch as any).liked_by,
      } as Partial<Status>
      updateRowInThread(id, fields)
    },
  })

  const deleteMutation = useMutation({
    mutationFn: async (id: string) => {
      const res = await deleteStatus({ id })
      return res as Status
    },
    onSuccess: (deleted) => {
      removeRowFromThread(deleted.id)
    },
  })

  const likeRow = useCallback(
    (row: Status) => {
      likeMutation.mutate({
        id: row.id,
        favourited: !!row.favourited,
      })
    },
    [likeMutation]
  )

  const deleteRow = useCallback(
    async (id: string) => {
      const ok = await confirm({
        title: 'Delete post?',
        message: 'This cannot be undone.',
        confirmLabel: 'Delete',
        destructive: true,
      })
      if (ok) deleteMutation.mutate(id)
    },
    [confirm, deleteMutation]
  )

  return {
    likeRow,
    deleteRow,
    confirmDialog,
  }
}

export type UseThreadActions = ReturnType<typeof useThreadActions>
