'use client'

import { useMemo, useState, useTransition } from 'react'
import { useRouter } from 'next/navigation'
import {
  DndContext,
  DragOverlay,
  PointerSensor,
  KeyboardSensor,
  useDroppable,
  useSensor,
  useSensors,
  closestCorners,
  type DragEndEvent,
  type DragStartEvent,
} from '@dnd-kit/core'
import {
  SortableContext,
  sortableKeyboardCoordinates,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable'
import IntakeCard from './intake-card'
import IntakeRejectModal from './intake-reject-modal'
import IntakePromoteModal from './intake-promote-modal'
import IntakeReviewerPickerModal from './intake-reviewer-picker-modal'
import { moveIntakeStatus, rejectIntake } from '@/app/intake/board/actions'

export type BoardStatus = 'backlog' | 'review'

export type BoardIntake = {
  id: string
  intake_id: string
  status: 'draft' | 'backlog' | 'review' | 'promoted' | 'rejected' | 'archived'
  project_lead: string | null
  intake_type: string | null
  requesting_department: string | null
  supplier_name: string | null
  priority: 'low' | 'normal' | 'high' | 'escalation'
  desired_visit_start: string | null
  desired_visit_end: string | null
  reviewing_consultant_id: string | null
  reviewing_consultant_name: string | null
  updated_at: string
}

type Props = {
  initialIntakes: BoardIntake[]
}

const COLUMNS: { id: BoardStatus; label: string; hint: string }[] = [
  { id: 'backlog', label: 'Backlog', hint: 'Neu eingegangen' },
  { id: 'review',  label: 'In Review', hint: 'Berater plant' },
]

export default function IntakeBoard({ initialIntakes }: Props) {
  const router = useRouter()
  const [intakes, setIntakes] = useState<BoardIntake[]>(initialIntakes)
  const [activeId, setActiveId] = useState<string | null>(null)
  const [rejectTarget, setRejectTarget] = useState<BoardIntake | null>(null)
  const [promoteTarget, setPromoteTarget] = useState<BoardIntake | null>(null)
  const [reviewTarget, setReviewTarget] = useState<{ intake: BoardIntake; fromStatus: BoardStatus } | null>(null)
  const [successMsg, setSuccessMsg] = useState<string | null>(null)
  const [errorMsg, setErrorMsg] = useState<string | null>(null)
  const [isPending, startTransition] = useTransition()

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 6 } }),
    useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
  )

  const byColumn = useMemo(() => {
    const map: Record<BoardStatus, BoardIntake[]> = { backlog: [], review: [] }
    for (const i of intakes) {
      if (i.status === 'backlog' || i.status === 'review') {
        map[i.status].push(i)
      }
    }
    return map
  }, [intakes])

  const activeIntake = activeId ? intakes.find((i) => i.id === activeId) ?? null : null

  function handleDragStart(event: DragStartEvent) {
    setActiveId(String(event.active.id))
    setErrorMsg(null)
  }

  function handleDragEnd(event: DragEndEvent) {
    setActiveId(null)
    const { active, over } = event
    if (!over) return

    const intake = intakes.find((i) => i.id === String(active.id))
    if (!intake) return

    const targetCol = resolveColumn(String(over.id), intakes)
    if (!targetCol) return
    if (targetCol === intake.status) return

    const prevStatus = intake.status as BoardStatus

    // backlog → review: erst Reviewer wählen, dann move
    if (prevStatus === 'backlog' && targetCol === 'review') {
      setReviewTarget({ intake, fromStatus: prevStatus })
      return
    }

    setIntakes((prev) =>
      prev.map((i) => (i.id === intake.id ? { ...i, status: targetCol } : i)),
    )

    startTransition(async () => {
      const result = await moveIntakeStatus(intake.id, prevStatus, targetCol)
      if (!result.ok) {
        setIntakes((prev) =>
          prev.map((i) => (i.id === intake.id ? { ...i, status: prevStatus } : i)),
        )
        setErrorMsg(`Verschieben fehlgeschlagen: ${result.error}`)
      } else {
        router.refresh()
      }
    })
  }

  function handleReviewerConfirm(consultantId: string, consultantDisplayName: string) {
    if (!reviewTarget) return
    const { intake, fromStatus } = reviewTarget
    setReviewTarget(null)

    setIntakes((prev) =>
      prev.map((i) =>
        i.id === intake.id
          ? {
              ...i,
              status: 'review' as const,
              reviewing_consultant_id: consultantId,
              reviewing_consultant_name: consultantDisplayName,
            }
          : i,
      ),
    )

    startTransition(async () => {
      const result = await moveIntakeStatus(intake.id, fromStatus, 'review', consultantId)
      if (!result.ok) {
        setIntakes((prev) =>
          prev.map((i) =>
            i.id === intake.id
              ? {
                  ...i,
                  status: fromStatus,
                  reviewing_consultant_id: intake.reviewing_consultant_id,
                  reviewing_consultant_name: intake.reviewing_consultant_name,
                }
              : i,
          ),
        )
        setErrorMsg(`Reviewer-Zuweisung fehlgeschlagen: ${result.error}`)
      } else {
        router.refresh()
      }
    })
  }

  function handleReject(target: BoardIntake) {
    setRejectTarget(target)
  }

  function handlePromote(target: BoardIntake) {
    setPromoteTarget(target)
  }

  function handlePromoteSuccess(result: { project_id: string; project_code: string }) {
    const target = promoteTarget
    setPromoteTarget(null)
    if (target) {
      setIntakes((prev) => prev.filter((i) => i.id !== target.id))
    }
    setSuccessMsg(`Projekt ${result.project_code} angelegt`)
    router.refresh()
  }

  function handleRejectConfirm(reasonCode: string, freeText: string) {
    if (!rejectTarget) return
    const target = rejectTarget
    const prevStatus = target.status as BoardStatus

    setIntakes((prev) => prev.filter((i) => i.id !== target.id))
    setRejectTarget(null)

    startTransition(async () => {
      const result = await rejectIntake(
        target.id,
        prevStatus,
        reasonCode as Parameters<typeof rejectIntake>[2],
        freeText.trim() || null,
      )
      if (!result.ok) {
        setIntakes((prev) => [...prev, target])
        setErrorMsg(`Ablehnen fehlgeschlagen: ${result.error}`)
      } else {
        router.refresh()
      }
    })
  }

  return (
    <>
      {errorMsg && (
        <div
          role="alert"
          className="px-4 py-3 bg-destructive/10 border border-destructive/30 text-destructive text-sm rounded-sm"
        >
          {errorMsg}
        </div>
      )}

      {successMsg && (
        <div
          role="status"
          className="px-4 py-3 bg-success/10 border border-success/30 text-success text-sm rounded-sm flex items-center justify-between gap-3"
        >
          <span>{successMsg}</span>
          <button
            type="button"
            onClick={() => setSuccessMsg(null)}
            className="text-xs font-condensed text-foreground/80 hover:underline"
          >
            schließen
          </button>
        </div>
      )}

      <DndContext
        sensors={sensors}
        collisionDetection={closestCorners}
        onDragStart={handleDragStart}
        onDragEnd={handleDragEnd}
      >
        <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
          {COLUMNS.map((col) => (
            <BoardColumn
              key={col.id}
              column={col}
              items={byColumn[col.id]}
              onReject={handleReject}
              onPromote={handlePromote}
              isPending={isPending}
            />
          ))}
        </div>

        <DragOverlay>
          {activeIntake ? (
            <div className="opacity-90 rotate-1 scale-105">
              <IntakeCard intake={activeIntake} draggable={false} />
            </div>
          ) : null}
        </DragOverlay>
      </DndContext>

      {rejectTarget && (
        <IntakeRejectModal
          intake={rejectTarget}
          onCancel={() => setRejectTarget(null)}
          onConfirm={handleRejectConfirm}
        />
      )}

      {promoteTarget && (
        <IntakePromoteModal
          intakeRef={{ id: promoteTarget.id, intake_id: promoteTarget.intake_id }}
          onCancel={() => setPromoteTarget(null)}
          onSuccess={handlePromoteSuccess}
        />
      )}

      {reviewTarget && (
        <IntakeReviewerPickerModal
          intakeNumber={reviewTarget.intake.intake_id}
          onCancel={() => setReviewTarget(null)}
          onConfirm={handleReviewerConfirm}
        />
      )}
    </>
  )
}

function resolveColumn(overId: string, intakes: BoardIntake[]): BoardStatus | null {
  if (overId === 'backlog' || overId === 'review') return overId
  const target = intakes.find((i) => i.id === overId)
  if (!target) return null
  if (target.status === 'backlog' || target.status === 'review') return target.status
  return null
}

type ColumnProps = {
  column: { id: BoardStatus; label: string; hint: string }
  items: BoardIntake[]
  onReject: (intake: BoardIntake) => void
  onPromote: (intake: BoardIntake) => void
  isPending: boolean
}

function BoardColumn({ column, items, onReject, onPromote, isPending }: ColumnProps) {
  return (
    <section
      aria-label={`Spalte ${column.label}`}
      className="flex flex-col bg-muted/40 border border-border rounded-md min-h-[400px]"
    >
      <header className="px-4 py-3 border-b border-border flex items-center justify-between">
        <div>
          <h2 className="text-sm font-bold text-foreground">{column.label}</h2>
          <p className="text-xs text-muted-foreground">{column.hint}</p>
        </div>
        <span
          aria-label={`${items.length} Aufträge`}
          className="text-xs font-condensed font-bold bg-card border border-border rounded-full px-2 py-0.5"
        >
          {items.length}
        </span>
      </header>

      <SortableContext id={column.id} items={items.map((i) => i.id)} strategy={verticalListSortingStrategy}>
        <ColumnDropArea id={column.id}>
          {items.length === 0 ? (
            <p className="px-4 py-8 text-xs text-center text-muted-foreground italic">
              Leer
            </p>
          ) : (
            <ul className="flex flex-col gap-3 p-3" aria-busy={isPending}>
              {items.map((intake) => (
                <li key={intake.id}>
                  <IntakeCard intake={intake} onReject={onReject} onPromote={onPromote} />
                </li>
              ))}
            </ul>
          )}
        </ColumnDropArea>
      </SortableContext>
    </section>
  )
}

type DropAreaProps = {
  id: BoardStatus
  children: React.ReactNode
}

function ColumnDropArea({ id, children }: DropAreaProps) {
  const { setNodeRef, isOver } = useDroppable({ id })
  return (
    <div
      ref={setNodeRef}
      className={`flex-1 transition-colors ${isOver ? 'bg-primary/5' : ''}`}
    >
      {children}
    </div>
  )
}
