'use client'

// PBI-74 / Story 9: Sprint workspace hydration wrapper.
//
// Server-component (sprint page) fetcht initial sprint snapshot; deze wrapper
// hydreert useSprintWorkspaceStore op client-mount, mount de SSE-hook en de
// resync-laag.

import { useEffect, useRef } from 'react'
import { useSprintRealtime } from '@/lib/realtime/use-sprint-realtime'
import { useSprintWorkspaceResync } from '@/lib/realtime/use-sprint-workspace-resync'
import { useSprintWorkspaceStore } from '@/stores/sprint-workspace/store'
import type {
  SprintWorkspaceSnapshot,
  SprintWorkspaceSprint,
  SprintWorkspaceStory,
  SprintWorkspaceTask,
} from '@/stores/sprint-workspace/types'

export interface SprintHydrationData {
  sprint: SprintWorkspaceSprint
  stories: SprintWorkspaceStory[]
  tasksByStory: Record<string, SprintWorkspaceTask[]>
}

interface SprintHydrationWrapperProps {
  initialData: SprintHydrationData
  productId: string
  productName?: string
  children: React.ReactNode
}

function fingerprint(data: SprintHydrationData): string {
  const sprintPart = `${data.sprint.id}:${data.sprint.status}`
  const storyPart = data.stories
    .map((s) => `${s.id}:${s.status}:${s.sprint_id ?? 'null'}:${s.sort_order}`)
    .join(',')
  const taskPart = Object.entries(data.tasksByStory)
    .flatMap(([, list]) => list.map((t) => `${t.id}:${t.status}:${t.sort_order}`))
    .join(',')
  return `${sprintPart}|${storyPart}|${taskPart}`
}

function toWorkspaceSnapshot(
  data: SprintHydrationData,
  productId: string,
  productName: string | undefined,
): SprintWorkspaceSnapshot {
  return {
    product: { id: productId, name: productName ?? '' },
    sprint: data.sprint,
    stories: data.stories,
    tasksByStory: data.tasksByStory,
  }
}

export function SprintHydrationWrapper({
  initialData,
  productId,
  productName,
  children,
}: SprintHydrationWrapperProps) {
  const lastFingerprint = useRef<string>('')

  useEffect(() => {
    const fp = fingerprint(initialData)
    if (fp !== lastFingerprint.current) {
      lastFingerprint.current = fp
      useSprintWorkspaceStore
        .getState()
        .hydrateSnapshot(toWorkspaceSnapshot(initialData, productId, productName))
      // T-880 schaduw-fase: zet activeSprintId zodat selectors meteen werken
      useSprintWorkspaceStore.setState((s) => {
        s.context.activeSprintId = initialData.sprint.id
        s.context.activeProduct = { id: productId, name: productName ?? '' }
      })
    }
  }, [initialData, productId, productName])

  useSprintRealtime(productId)
  useSprintWorkspaceResync()

  return <>{children}</>
}
