import { Suspense } from 'react'
import { notFound, redirect } from 'next/navigation'
import { getSession } from '@/lib/auth'
import { getAccessibleProduct } from '@/lib/product-access'
import { prisma } from '@/lib/prisma'
import { pbiStatusToApi } from '@/lib/task-status'
import { getSprintSwitcherData } from '@/lib/sprint-switcher-data'
import { BacklogSplitPane } from '@/components/backlog/backlog-split-pane'
import { PbiList } from '@/components/backlog/pbi-list'
import { StoryPanel } from '@/components/backlog/story-panel'
import type { Story } from '@/components/backlog/story-panel'
import { TaskPanel } from '@/components/backlog/task-panel'
import { BacklogHydrationWrapper } from '@/components/backlog/backlog-hydration-wrapper'
import { UrlTaskSync } from '@/components/backlog/url-task-sync'
import { TaskDialog } from '@/app/_components/tasks/task-dialog'
import { EditTaskLoader } from '@/app/_components/tasks/edit-task-loader'
import { TaskDialogSkeleton } from '@/app/_components/tasks/task-dialog-skeleton'
import { NewSprintTrigger } from '@/components/backlog/new-sprint-trigger'
import { SprintDraftBanner } from '@/components/backlog/sprint-draft-banner'
import { SprintDraftLeaveGuard } from '@/components/backlog/sprint-draft-leave-guard'
import { SaveSprintButton } from '@/components/backlog/save-sprint-button'
import { ActiveSelectionHydrator } from '@/components/backlog/active-selection-hydrator'
import { ActivateProductButton } from '@/components/shared/activate-product-button'
import { EditProductButton } from '@/components/products/edit-product-button'
import { SprintSwitcher } from '@/components/shared/sprint-switcher'
import Link from 'next/link'

interface Props {
  params: Promise<{ id: string }>
  searchParams: Promise<{ newTask?: string; storyId?: string; editTask?: string }>
}

export default async function ProductBacklogPage({ params, searchParams }: Props) {
  const { id } = await params
  const { newTask, storyId: storyIdParam, editTask } = await searchParams
  const closePath = `/products/${id}`
  const session = await getSession()
  if (!session.userId) redirect('/login')

  const product = await getAccessibleProduct(id, session.userId)
  if (!product) notFound()

  const [user, switcherData] = await Promise.all([
    prisma.user.findUnique({ where: { id: session.userId! }, select: { active_product_id: true } }),
    getSprintSwitcherData(id, { userId: session.userId }),
  ])
  const { sprintItems, buildingSprintIds, activeSprintItem } = switcherData
  const hasOpenSprint = sprintItems.some(s => s.status === 'open')
  const isActiveProduct = user?.active_product_id === id

  const pbis = await prisma.pbi.findMany({
    where: { product_id: id },
    orderBy: [{ priority: 'asc' }, { sort_order: 'asc' }],
  })

  const [stories, tasks] = await Promise.all([
    prisma.story.findMany({
      where: { product_id: id },
      orderBy: [{ sort_order: 'asc' }, { created_at: 'asc' }],
      select: {
        id: true,
        code: true,
        title: true,
        description: true,
        acceptance_criteria: true,
        priority: true,
        sort_order: true,
        status: true,
        pbi_id: true,
        sprint_id: true,
        created_at: true,
      },
    }),
    prisma.task.findMany({
      where: { story: { pbi: { product_id: id } } },
      select: {
        id: true,
        code: true,
        title: true,
        description: true,
        priority: true,
        status: true,
        sort_order: true,
        story_id: true,
        created_at: true,
      },
      orderBy: [{ sort_order: 'asc' }, { created_at: 'asc' }],
    }),
  ])

  // Group stories by PBI id (status uit DB blijft UPPER_SNAKE in dit hydratie-pad)
  const storiesByPbi: Record<string, Story[]> = {}
  for (const story of stories) {
    if (!storiesByPbi[story.pbi_id]) storiesByPbi[story.pbi_id] = []
    storiesByPbi[story.pbi_id].push(story)
  }

  // Group tasks by story id
  const tasksByStory: Record<string, typeof tasks> = {}
  for (const task of tasks) {
    if (!tasksByStory[task.story_id]) tasksByStory[task.story_id] = []
    tasksByStory[task.story_id].push(task)
  }

  const isDemo = session.isDemo ?? false

  return (
    <div className="flex flex-col h-full">
      {/* Product header — sprint-switcher gecentreerd, actions rechts */}
      <div className="px-4 py-3 border-b border-border bg-surface-container-low shrink-0 flex items-center gap-3">
        <div className="flex-1" />
        <div className="flex items-center justify-center">
          {isActiveProduct && (
            <SprintSwitcher
              productId={id}
              sprints={sprintItems}
              activeSprint={activeSprintItem}
              buildingSprintIds={buildingSprintIds}
            />
          )}
        </div>
        <div className="flex-1 flex items-center gap-3 justify-end">
          {!isActiveProduct && (
            <ActivateProductButton productId={id} isDemo={isDemo} redirectTo={`/products/${id}`} />
          )}
          {hasOpenSprint && (
            <Link href={`/products/${id}/sprint`} className="text-xs text-primary hover:underline font-medium">
              Sprint actief →
            </Link>
          )}
          {activeSprintItem && !isDemo && (
            <SaveSprintButton activeSprintId={activeSprintItem.id} />
          )}
          {!isDemo && (
            <NewSprintTrigger
              productId={id}
              isDemo={isDemo}
              isActiveProduct={isActiveProduct}
            />
          )}
          {!isDemo && product.user_id === session.userId && (
            <EditProductButton
              product={{
                id: product.id,
                name: product.name,
                code: product.code,
                description: product.description,
                repo_url: product.repo_url,
                definition_of_done: product.definition_of_done,
                auto_pr: product.auto_pr,
              }}
            />
          )}
          <Link
            href={`/products/${id}/settings`}
            className="text-xs text-muted-foreground hover:text-foreground"
          >
            Instellingen
          </Link>
        </div>
      </div>

      {/* Sprint definition banner (state A′) + beforeunload-guard */}
      <SprintDraftBanner productId={id} />
      <SprintDraftLeaveGuard productId={id} />

      {/* Split pane */}
      <div className="flex-1 overflow-hidden">
        <BacklogHydrationWrapper
          productId={id}
          productName={product.name}
          initialData={{
            pbis: pbis.map((p) => ({ id: p.id, code: p.code, title: p.title, priority: p.priority, sort_order: p.sort_order, description: p.description, created_at: p.created_at, status: pbiStatusToApi(p.status) })),
            storiesByPbi,
            tasksByStory,
          }}
        >
          <UrlTaskSync />
          <ActiveSelectionHydrator productId={id} />
          <BacklogSplitPane
            cookieKey={`backlog-${id}`}
            defaultSplit={[20, 45, 35]}
            tabLabels={['PBI\'s', 'Stories', 'Taken']}
            panes={[
              <PbiList
                key="pbi"
                productId={id}
                isDemo={isDemo}
                activeSprintId={activeSprintItem?.id ?? null}
              />,
              <StoryPanel
                key="story"
                productId={id}
                isDemo={isDemo}
                activeSprintId={activeSprintItem?.id ?? null}
              />,
              <TaskPanel
                key="tasks"
                productId={id}
                isDemo={isDemo}
                closePath={closePath}
              />,
            ]}
          />
        </BacklogHydrationWrapper>
      </div>

      {newTask && (
        <TaskDialog
          storyId={storyIdParam}
          productId={id}
          closePath={closePath}
          isDemo={isDemo}
        />
      )}

      {editTask && !newTask && (
        <Suspense fallback={<TaskDialogSkeleton />}>
          <EditTaskLoader
            taskId={editTask}
            userId={session.userId}
            productId={id}
            closePath={closePath}
            isDemo={isDemo}
          />
        </Suspense>
      )}
    </div>
  )
}
