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 { SprintBoardClient } from '@/components/sprint/sprint-board-client'
import { SprintHeader } from '@/components/sprint/sprint-header'
import type { SprintStory, PbiWithStories, ProductMember } from '@/components/sprint/sprint-backlog'
import type { Task } from '@/components/sprint/task-list'
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 Link from 'next/link'

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

export default async function SprintBoardPage({ params, searchParams }: Props) {
  const { id } = await params
  const { newTask, storyId: storyIdParam, editTask } = await searchParams

  const session = await getSession()
  if (!session.userId) redirect('/login')

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

  const sprint = await prisma.sprint.findFirst({
    where: { product_id: id, status: 'ACTIVE' },
    select: {
      id: true,
      sprint_goal: true,
      status: true,
      start_date: true,
      end_date: true,
    },
  })
  if (!sprint) redirect(`/products/${id}`)

  // Sprint stories with full task data and assignee
  const [sprintStories, productMembers] = await Promise.all([
    prisma.story.findMany({
      where: { sprint_id: sprint.id },
      orderBy: { sort_order: 'asc' },
      include: {
        tasks: { orderBy: [{ priority: 'asc' }, { sort_order: 'asc' }] },
        assignee: { select: { id: true, username: true } },
      },
    }),
    prisma.productMember.findMany({
      where: { product_id: id },
      include: { user: { select: { id: true, username: true } } },
    }),
  ])

  // All members who can be assigned: owner + product members
  const members: ProductMember[] = [
    { userId: product.user_id, username: (await prisma.user.findUnique({ where: { id: product.user_id }, select: { username: true } }))?.username ?? 'Eigenaar' },
    ...productMembers.map(m => ({ userId: m.user_id, username: m.user.username })),
  ]

  const sprintStoryItems: SprintStory[] = sprintStories.map(s => ({
    id: s.id,
    code: s.code,
    title: s.title,
    description: s.description,
    acceptance_criteria: s.acceptance_criteria,
    pbi_id: s.pbi_id,
    created_at: s.created_at,
    priority: s.priority,
    status: s.status,
    taskCount: s.tasks.length,
    doneCount: s.tasks.filter(t => t.status === 'DONE').length,
    assignee_id: s.assignee_id,
    assignee_username: s.assignee?.username ?? null,
  }))

  const tasksByStory: Record<string, Task[]> = {}
  for (const story of sprintStories) {
    tasksByStory[story.id] = story.tasks.map(t => ({
      id: t.id,
      code: t.code,
      title: t.title,
      description: t.description,
      priority: t.priority,
      status: t.status,
      story_id: t.story_id,
      sprint_id: t.sprint_id,
    }))
  }

  // All PBIs with their stories for the left (product backlog) panel
  const pbis = await prisma.pbi.findMany({
    where: { product_id: id },
    orderBy: [{ priority: 'asc' }, { sort_order: 'asc' }],
    include: {
      stories: {
        orderBy: [{ priority: 'asc' }, { sort_order: 'asc' }],
      },
    },
  })

  const pbisWithStories: PbiWithStories[] = pbis
    .filter(pbi => pbi.stories.length > 0)
    .map(pbi => ({
      id: pbi.id,
      code: pbi.code,
      title: pbi.title,
      priority: pbi.priority,
      status: pbiStatusToApi(pbi.status),
      description: pbi.description,
      stories: pbi.stories.map(s => ({
        id: s.id,
        code: s.code,
        title: s.title,
        description: s.description,
        acceptance_criteria: s.acceptance_criteria,
        pbi_id: s.pbi_id,
        created_at: s.created_at,
        priority: s.priority,
        status: s.status,
        taskCount: 0,
        doneCount: 0,
        assignee_id: null,
        assignee_username: null,
      })),
    }))

  const sprintStoryIdList = sprintStories.map(s => s.id)
  const isDemo = session.isDemo ?? false
  const closePath = `/products/${id}/sprint`

  return (
    <div className="flex flex-col h-full">
      <SprintHeader
        productId={id}
        productName={product.name}
        sprint={sprint}
        isDemo={isDemo}
        sprintStories={sprintStoryItems}
      />

      <div className="flex-1 overflow-hidden">
        <SprintBoardClient
          productId={id}
          sprintId={sprint.id}
          stories={sprintStoryItems}
          pbisWithStories={pbisWithStories}
          sprintStoryIdList={sprintStoryIdList}
          tasksByStory={tasksByStory}
          isDemo={isDemo}
          currentUserId={session.userId}
          members={members}
        />
      </div>

      <div className="border-t border-border px-4 py-2 bg-surface-container-low shrink-0">
        <Link href={`/products/${id}`} className="text-sm text-muted-foreground hover:text-foreground">
          ← Product Backlog
        </Link>
      </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>
  )
}
