import { afterEach, describe, expect, it, vi } from 'vitest'
import { queryClient, queryKeys } from '../src/api/queryClient'
import { applyTaskBoardCardDelta, type TaskBoardCardDto, type TaskBoardPageDto } from '../src/api/taskBoard'

afterEach(() => {
  queryClient.clear()
})

describe('canonical server-state query cache', () => {
  it('deduplicates three simultaneous consumers into one HTTP query', async () => {
    let resolveRequest: ((value: string[]) => void) | undefined
    const response = new Promise<string[]>(resolve => {
      resolveRequest = resolve
    })
    const queryFn = vi.fn(() => response)
    const options = {
      queryKey: queryKeys.projects(),
      queryFn,
      staleTime: 15_000,
    }

    const consumers = [
      queryClient.fetchQuery(options),
      queryClient.fetchQuery(options),
      queryClient.fetchQuery(options),
    ]

    expect(queryFn).toHaveBeenCalledTimes(1)
    resolveRequest?.(['project-1'])
    await expect(Promise.all(consumers)).resolves.toEqual([
      ['project-1'],
      ['project-1'],
      ['project-1'],
    ])
    expect(queryFn).toHaveBeenCalledTimes(1)
  })

  it('moves a persisted task delta between board columns without a full snapshot', () => {
    const card: TaskBoardCardDto = {
      id: '0d2d33d7-bafa-4510-b135-c6a96021957a',
      title: 'Release review',
      detail: null,
      source: 'bao',
      state: 'Backlog',
      priority: 'Medium',
      assignedTo: 'bao',
      parentTaskId: null,
      projectId: null,
      dueDate: null,
      createdAt: '2026-07-31T08:00:00.000Z',
      updatedAt: '2026-07-31T08:00:00.000Z',
      isAgentTask: false,
      expectedFrom: null,
      lastActivityMessage: null,
      lastActivityAt: null,
      childTaskCount: 0,
      openChildTaskCount: 0,
      hasVisibleDelegation: false,
    }
    const page: TaskBoardPageDto = {
      revision: 'board-r1',
      offen: [card],
      inProgress: [],
      review: [],
      blocked: [],
      done: [],
      nextDoneCursor: null,
      hasMoreDone: false,
    }
    queryClient.setQueryData(queryKeys.taskBoard(50), {
      pages: [page],
      pageParams: [null],
    })

    applyTaskBoardCardDelta({
      ...card,
      state: 'Review',
      updatedAt: '2026-07-31T08:01:00.000Z',
    })

    const result = queryClient.getQueryData<{
      pages: TaskBoardPageDto[]
      pageParams: Array<string | null>
    }>(queryKeys.taskBoard(50))
    expect(result?.pages[0]?.offen).toEqual([])
    expect(result?.pages[0]?.review.map(item => item.id)).toEqual([card.id])
  })
})
