import { beforeEach, describe, expect, it, vi } from 'vitest'
import { useSoloStore } from '@/stores/solo-store'
import type { RealtimeEvent } from '@/stores/solo-store'
import type { SoloTask, SoloWorkspaceSnapshot } from '@/stores/solo-workspace/types'

function baseTask(id: string, overrides: Partial<SoloTask> = {}): SoloTask {
  return {
    id,
    title: `Task ${id}`,
    description: null,
    implementation_plan: null,
    priority: 1,
    sort_order: 1,
    status: 'TO_DO',
    verify_only: false,
    verify_required: 'ALIGNED_OR_PARTIAL',
    story_id: 'story-1',
    story_code: 'ST-1',
    story_title: 'Story 1',
    task_code: `ST-1.${id}`,
    pbi_code: null,
    pbi_title: null,
    pbi_description: null,
    ...overrides,
  }
}

function snapshot(tasks: SoloTask[]): SoloWorkspaceSnapshot {
  return {
    product: { id: 'prod-1', name: 'Product 1' },
    sprint: { id: 'sprint-1', sprint_goal: 'Goal' },
    activeUserId: 'user-1',
    tasks,
    unassignedStories: [
      { id: 'story-b', code: 'ST-2', title: 'Story B', tasks: [] },
      { id: 'story-a', code: 'ST-1', title: 'Story A', tasks: [] },
    ],
  }
}

function taskEvent(overrides: Partial<RealtimeEvent>): RealtimeEvent {
  return {
    op: 'U',
    entity: 'task',
    id: 'task-1',
    story_id: 'story-1',
    product_id: 'prod-1',
    sprint_id: 'sprint-1',
    assignee_id: 'user-1',
    ...overrides,
  }
}

beforeEach(() => {
  useSoloStore.setState({
    context: { activeProduct: null, activeSprint: null, activeUserId: null },
    entities: { tasksById: {}, unassignedStoriesById: {}, jobsByTaskId: {} },
    relations: {
      taskIdsByColumn: { TO_DO: [], IN_PROGRESS: [], DONE: [] },
      unassignedStoryIds: [],
    },
    loading: {
      loadedProductId: null,
      loadedSprintId: null,
      loadingSprintId: null,
      activeRequestId: null,
    },
    sync: {
      realtimeStatus: 'connecting',
      showConnectingIndicator: false,
      lastEventAt: null,
      lastResyncAt: null,
      resyncReason: null,
    },
    pendingOps: new Set(),
    tasks: {},
    unassignedStoriesById: {},
    claudeJobsByTaskId: {},
  })
  vi.restoreAllMocks()
})

describe('solo workspace store', () => {
  it('hydrateert genormaliseerde taken, kolomrelaties en unassigned stories', () => {
    useSoloStore.getState().hydrateSnapshot(
      snapshot([
        baseTask('task-2', { status: 'DONE', sort_order: 2 }),
        baseTask('task-1', { status: 'TO_DO', sort_order: 1 }),
        baseTask('task-3', { status: 'REVIEW', sort_order: 3 }),
      ]),
    )

    const s = useSoloStore.getState()
    expect(s.context.activeSprint?.id).toBe('sprint-1')
    expect(s.relations.taskIdsByColumn.TO_DO).toEqual(['task-1'])
    expect(s.relations.taskIdsByColumn.IN_PROGRESS).toEqual(['task-3'])
    expect(s.relations.taskIdsByColumn.DONE).toEqual(['task-2'])
    expect(s.relations.unassignedStoryIds).toEqual(['story-a', 'story-b'])
  })

  it('past realtime task updates toe en herbouwt kolomrelaties', () => {
    useSoloStore.getState().hydrateSnapshot(snapshot([baseTask('task-1')]))
    useSoloStore.getState().handleRealtimeEvent(
      taskEvent({ status: 'DONE', sort_order: 5, title: 'Done task' }),
    )

    const s = useSoloStore.getState()
    expect(s.tasks['task-1'].status).toBe('DONE')
    expect(s.tasks['task-1'].title).toBe('Done task')
    expect(s.relations.taskIdsByColumn.TO_DO).toEqual([])
    expect(s.relations.taskIdsByColumn.DONE).toEqual(['task-1'])
  })

  it('resynct actieve scopes via de solo-workspace route', async () => {
    useSoloStore.getState().hydrateSnapshot(snapshot([baseTask('task-1')]))
    const next = snapshot([baseTask('task-1', { status: 'IN_PROGRESS' })])
    const fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValue(
      new Response(JSON.stringify(next), { status: 200 }),
    )

    await useSoloStore.getState().resyncActiveScopes('manual')

    expect(fetchSpy).toHaveBeenCalledWith(
      '/api/products/prod-1/solo-workspace?sprint_id=sprint-1',
      expect.objectContaining({ cache: 'no-store' }),
    )
    const s = useSoloStore.getState()
    expect(s.tasks['task-1'].status).toBe('IN_PROGRESS')
    expect(s.sync.resyncReason).toBe('manual')
  })
})
