'use client'

import { useMemo, useState } from 'react'
import Link from 'next/link'
import { toast } from 'sonner'
import { trpc } from '@/lib/trpc/client'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Skeleton } from '@/components/ui/skeleton'
import { Checkbox } from '@/components/ui/checkbox'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import {
  Search,
  UserPlus,
  ArrowRight,
  Sparkles,
  Loader2,
  Download,
  X,
} from 'lucide-react'
import { CountryDisplay } from '@/components/shared/country-display'

type Filter = 'all' | 'unassigned' | 'assigned' | 'wants_only'

export function MentoringProjectsTable({ roundId }: { roundId: string }) {
  const [search, setSearch] = useState('')
  const [filter, setFilter] = useState<Filter>('all')
  const [selected, setSelected] = useState<Set<string>>(new Set())
  const [bulkOpen, setBulkOpen] = useState(false)
  const [chosenMentorId, setChosenMentorId] = useState<string>('')
  const [mentorSearch, setMentorSearch] = useState('')

  const utils = trpc.useUtils()

  const { data, isLoading } = trpc.round.listMentoringProjects.useQuery(
    { roundId },
    { refetchInterval: 30_000 },
  )

  const { data: importCandidates } =
    trpc.round.getMentoringImportCandidates.useQuery({ roundId })

  const { data: mentorPool } = trpc.mentor.getMentorPool.useQuery(
    {},
    { enabled: bulkOpen },
  )

  const bulkAssignMutation = trpc.mentor.bulkAssign.useMutation({
    onSuccess: (result) => {
      if (result.assignedCount === 0 && result.skippedCount > 0) {
        toast.info(
          `No new assignments — the selected mentor is already on all ${result.skippedCount} project${result.skippedCount === 1 ? '' : 's'}.`,
        )
      } else {
        toast.success(
          `Assigned mentor to ${result.assignedCount} project${
            result.assignedCount === 1 ? '' : 's'
          }${result.skippedCount > 0 ? ` (${result.skippedCount} already had this mentor)` : ''}${
            result.emailSent ? ' · email sent' : ''
          }`,
        )
      }
      utils.round.listMentoringProjects.invalidate({ roundId })
      utils.round.getProjectsNeedingMentor.invalidate({ roundId })
      utils.round.getMentoringImportCandidates.invalidate({ roundId })
      utils.mentor.getMentorPool.invalidate()
      utils.mentor.getRoundStats.invalidate({ roundId })
      utils.project.list.invalidate()
      setSelected(new Set())
      setChosenMentorId('')
      setMentorSearch('')
      setBulkOpen(false)
    },
    onError: (err) => toast.error(err.message),
  })

  const advanceMutation = trpc.round.advanceProjects.useMutation({
    onSuccess: (result) => {
      toast.success(
        `Imported ${result.advancedCount} project${
          result.advancedCount === 1 ? '' : 's'
        } from ${result.targetRoundName ? '' : ''}${
          importCandidates?.priorRound?.name ?? 'the prior round'
        }`,
      )
      utils.round.listMentoringProjects.invalidate({ roundId })
      utils.round.getMentoringImportCandidates.invalidate({ roundId })
      utils.round.getProjectsNeedingMentor.invalidate({ roundId })
    },
    onError: (err) => toast.error(err.message),
  })

  const importBanner = importCandidates?.priorRound &&
    importCandidates.pendingCount > 0 && (
      <div className="flex flex-col gap-2 rounded-md border border-amber-300 bg-amber-50 px-4 py-3 text-sm sm:flex-row sm:items-center sm:justify-between">
        <div className="text-amber-900">
          <span className="font-medium">
            {importCandidates.pendingCount} PASSED project
            {importCandidates.pendingCount === 1 ? '' : 's'}
          </span>{' '}
          from{' '}
          <span className="font-medium">
            {importCandidates.priorRound.name}
          </span>{' '}
          {importCandidates.pendingCount === 1 ? "isn't" : "aren't"} in this
          mentoring round yet.
        </div>
        <Button
          size="sm"
          onClick={() =>
            advanceMutation.mutate({
              roundId: importCandidates.priorRound!.id,
              targetRoundId: roundId,
            })
          }
          disabled={advanceMutation.isPending}
        >
          {advanceMutation.isPending ? (
            <Loader2 className="mr-1.5 h-4 w-4 animate-spin" />
          ) : (
            <Download className="mr-1.5 h-4 w-4" />
          )}
          Import {importCandidates.pendingCount}
        </Button>
      </div>
    )

  const filtered = useMemo(() => {
    if (!data) return []
    const q = search.trim().toLowerCase()
    return data.projects.filter((p) => {
      if (filter === 'unassigned' && p.mentors.length > 0) return false
      if (filter === 'assigned' && p.mentors.length === 0) return false
      if (filter === 'wants_only' && !p.wantsMentorship) return false
      if (!q) return true
      const hay = [
        p.title,
        p.teamName ?? '',
        p.country ?? '',
        ...p.mentors.map((m) => m.name ?? m.email),
      ]
        .join(' ')
        .toLowerCase()
      return hay.includes(q)
    })
  }, [data, search, filter])

  const totals = useMemo(() => {
    if (!data)
      return { total: 0, unassigned: 0, assigned: 0, wants: 0 }
    return {
      total: data.projects.length,
      unassigned: data.projects.filter((p) => p.mentors.length === 0).length,
      assigned: data.projects.filter((p) => p.mentors.length > 0).length,
      wants: data.projects.filter((p) => p.wantsMentorship).length,
    }
  }, [data])

  if (isLoading) {
    return (
      <div className="space-y-2">
        {[1, 2, 3, 4, 5].map((i) => (
          <Skeleton key={i} className="h-14 w-full" />
        ))}
      </div>
    )
  }

  if (!data || data.projects.length === 0) {
    return (
      <div className="space-y-3">
        {importBanner}
        <div className="rounded-md border bg-muted/30 px-4 py-12 text-center text-sm text-muted-foreground">
          No projects in this mentoring round yet.
          {!importBanner && (
            <>
              {' '}Use{' '}
              <span className="font-medium text-foreground">
                Add Project to Round
              </span>{' '}
              to populate it.
            </>
          )}
        </div>
      </div>
    )
  }

  const Pill = ({
    value,
    label,
    count,
  }: {
    value: Filter
    label: string
    count: number
  }) => (
    <button
      type="button"
      onClick={() => setFilter(value)}
      className={`rounded-md border px-2.5 py-1 text-xs font-medium transition-colors ${
        filter === value
          ? 'border-primary bg-primary text-primary-foreground'
          : 'bg-background hover:bg-muted'
      }`}
    >
      {label}{' '}
      <span className="tabular-nums opacity-80">({count})</span>
    </button>
  )

  return (
    <div className="space-y-3">
      {importBanner}
      <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
        <div className="flex flex-wrap gap-1.5">
          <Pill value="all" label="All" count={totals.total} />
          <Pill value="unassigned" label="No mentor" count={totals.unassigned} />
          <Pill value="assigned" label="Has mentor" count={totals.assigned} />
          <Pill value="wants_only" label="Wants mentorship" count={totals.wants} />
        </div>
        <div className="relative w-full sm:max-w-xs">
          <Search className="absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" />
          <Input
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="Search projects, teams, or mentors…"
            className="pl-8"
          />
        </div>
      </div>

      {selected.size > 0 ? (
        <div className="flex flex-col gap-2 rounded-md border border-primary/30 bg-primary/5 px-4 py-2.5 text-sm sm:flex-row sm:items-center sm:justify-between">
          <div>
            <span className="font-medium">{selected.size}</span>{' '}
            <span className="text-muted-foreground">
              project{selected.size === 1 ? '' : 's'} selected
            </span>
          </div>
          <div className="flex flex-wrap gap-2">
            <Button size="sm" onClick={() => setBulkOpen(true)}>
              <UserPlus className="mr-1.5 h-4 w-4" />
              Assign mentor…
            </Button>
            <Button
              size="sm"
              variant="outline"
              onClick={() => setSelected(new Set())}
            >
              <X className="mr-1 h-4 w-4" />
              Clear
            </Button>
          </div>
        </div>
      ) : (
        <div className="flex items-center justify-between rounded-md border border-dashed bg-muted/20 px-4 py-2 text-xs text-muted-foreground">
          <span>
            Tip: tick checkboxes to bulk-assign one mentor to multiple
            projects in a single click (mentor gets one combined email).
          </span>
          {totals.unassigned > 0 && (
            <button
              type="button"
              className="text-xs font-medium text-foreground hover:underline"
              onClick={() => {
                setFilter('unassigned')
                setSelected(
                  new Set(
                    data.projects
                      .filter((p) => p.mentors.length === 0)
                      .map((p) => p.id),
                  ),
                )
              }}
            >
              Select all {totals.unassigned} without a mentor
            </button>
          )}
        </div>
      )}

      <div className="overflow-hidden rounded-md border">
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead className="w-10">
                <Checkbox
                  checked={
                    filtered.length > 0 &&
                    filtered.every((p) => selected.has(p.id))
                  }
                  onCheckedChange={(checked) => {
                    setSelected((prev) => {
                      const next = new Set(prev)
                      if (checked) {
                        filtered.forEach((p) => next.add(p.id))
                      } else {
                        filtered.forEach((p) => next.delete(p.id))
                      }
                      return next
                    })
                  }}
                  aria-label="Select all visible"
                />
              </TableHead>
              <TableHead>Project</TableHead>
              <TableHead>Wants?</TableHead>
              <TableHead>Mentors</TableHead>
              <TableHead className="w-32 text-right">Action</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {filtered.length === 0 ? (
              <TableRow>
                <TableCell
                  colSpan={5}
                  className="py-8 text-center text-sm text-muted-foreground"
                >
                  No projects match the current filter.
                </TableCell>
              </TableRow>
            ) : (
              filtered.map((p) => (
                <TableRow
                  key={p.id}
                  data-state={selected.has(p.id) ? 'selected' : undefined}
                >
                  <TableCell>
                    <Checkbox
                      checked={selected.has(p.id)}
                      onCheckedChange={(checked) =>
                        setSelected((prev) => {
                          const next = new Set(prev)
                          if (checked) next.add(p.id)
                          else next.delete(p.id)
                          return next
                        })
                      }
                      aria-label={`Select ${p.title}`}
                    />
                  </TableCell>
                  <TableCell>
                    <div className="font-medium">{p.title}</div>
                    <div className="text-xs text-muted-foreground">
                      {p.teamName ?? '—'}
                      {p.country && (
                        <>
                          {' · '}
                          <CountryDisplay country={p.country} />
                        </>
                      )}
                    </div>
                  </TableCell>
                  <TableCell>
                    <div className="flex flex-col gap-1">
                      {p.wantsMentorship ? (
                        <Badge variant="secondary" className="w-fit text-xs">
                          Requested
                        </Badge>
                      ) : (
                        <span className="text-xs text-muted-foreground">No</span>
                      )}
                      {p.finalistConfirmationStatus !== 'CONFIRMED' && (
                        <span
                          className="text-[10px] uppercase tracking-wide text-amber-700"
                          title="Auto-fill skips projects whose team has not confirmed attendance."
                        >
                          {p.finalistConfirmationStatus
                            ? p.finalistConfirmationStatus.toLowerCase()
                            : 'no confirmation'}
                        </span>
                      )}
                    </div>
                  </TableCell>
                  <TableCell>
                    {p.mentors.length === 0 ? (
                      <span className="text-xs italic text-muted-foreground">
                        Unassigned
                      </span>
                    ) : (
                      <div className="flex flex-wrap gap-1">
                        {p.mentors.map((m) => (
                          <Badge
                            key={m.assignmentId}
                            variant="outline"
                            className="gap-1 text-xs"
                            title={m.email}
                          >
                            {(m.method === 'AI_AUTO' ||
                              m.method === 'AI_SUGGESTED') && (
                              <Sparkles className="h-3 w-3 text-amber-500" />
                            )}
                            {m.name ?? m.email}
                          </Badge>
                        ))}
                      </div>
                    )}
                  </TableCell>
                  <TableCell className="text-right">
                    <Button asChild size="sm" variant="outline">
                      <Link href={`/admin/projects/${p.id}/mentor`}>
                        {p.mentors.length === 0 ? (
                          <>
                            <UserPlus className="mr-1 h-3.5 w-3.5" />
                            Assign
                          </>
                        ) : (
                          <>
                            Open
                            <ArrowRight className="ml-1 h-3.5 w-3.5" />
                          </>
                        )}
                      </Link>
                    </Button>
                  </TableCell>
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>
      </div>

      <Dialog
        open={bulkOpen}
        onOpenChange={(next) => {
          if (!next) {
            setBulkOpen(false)
            setChosenMentorId('')
            setMentorSearch('')
          }
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>
              Assign mentor to {selected.size} project
              {selected.size === 1 ? '' : 's'}
            </DialogTitle>
            <DialogDescription>
              Choose one mentor — they'll receive a single email listing every
              new assignment. Projects where they're already an active mentor
              will be skipped.
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-3">
            <div className="relative">
              <Search className="absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" />
              <Input
                value={mentorSearch}
                onChange={(e) => setMentorSearch(e.target.value)}
                placeholder="Search mentor by name, email, country, or expertise…"
                className="pl-8"
              />
            </div>
            <div className="max-h-72 overflow-y-auto rounded-md border">
              {(() => {
                const mentors = mentorPool?.mentors ?? []
                const q = mentorSearch.trim().toLowerCase()
                const filteredMentors = q
                  ? mentors.filter((m) =>
                      [
                        m.name ?? '',
                        m.email,
                        m.country ?? '',
                        ...(m.expertiseTags ?? []),
                      ]
                        .join(' ')
                        .toLowerCase()
                        .includes(q),
                    )
                  : mentors
                if (mentors.length === 0) {
                  return (
                    <p className="p-4 text-center text-sm text-muted-foreground">
                      No mentors in the pool yet.{' '}
                      <Link
                        href="/admin/members?tab=mentors"
                        className="underline-offset-2 hover:underline"
                      >
                        Add mentors
                      </Link>
                      .
                    </p>
                  )
                }
                if (filteredMentors.length === 0) {
                  return (
                    <p className="p-4 text-center text-sm text-muted-foreground">
                      No mentors match &ldquo;{mentorSearch}&rdquo;.
                    </p>
                  )
                }
                return filteredMentors.map((m) => {
                  const isChosen = chosenMentorId === m.id
                  return (
                    <label
                      key={m.id}
                      className={`flex cursor-pointer items-start gap-3 border-b px-3 py-2 text-sm last:border-b-0 ${
                        isChosen ? 'bg-accent' : 'hover:bg-muted/50'
                      }`}
                    >
                      <input
                        type="radio"
                        name="bulk-mentor"
                        className="mt-1"
                        checked={isChosen}
                        onChange={() => setChosenMentorId(m.id)}
                      />
                      <div className="min-w-0 flex-1">
                        <div className="font-medium">
                          {m.name ?? 'Unnamed'}
                        </div>
                        <div className="truncate text-xs text-muted-foreground">
                          {m.email}
                          {m.country && <> · {m.country}</>}
                        </div>
                        {m.expertiseTags && m.expertiseTags.length > 0 && (
                          <div className="mt-1 flex flex-wrap gap-1">
                            {m.expertiseTags.slice(0, 4).map((t) => (
                              <Badge
                                key={t}
                                variant="secondary"
                                className="text-[10px]"
                              >
                                {t}
                              </Badge>
                            ))}
                            {m.expertiseTags.length > 4 && (
                              <Badge variant="outline" className="text-[10px]">
                                +{m.expertiseTags.length - 4}
                              </Badge>
                            )}
                          </div>
                        )}
                      </div>
                      <div className="shrink-0 text-right text-xs tabular-nums text-muted-foreground">
                        {m.currentAssignments}
                        {m.maxAssignments != null && `/${m.maxAssignments}`}{' '}
                        load
                      </div>
                    </label>
                  )
                })
              })()}
            </div>
          </div>

          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => {
                setBulkOpen(false)
                setChosenMentorId('')
                setMentorSearch('')
              }}
            >
              Cancel
            </Button>
            <Button
              onClick={() =>
                bulkAssignMutation.mutate({
                  mentorId: chosenMentorId,
                  projectIds: Array.from(selected),
                })
              }
              disabled={!chosenMentorId || bulkAssignMutation.isPending}
            >
              {bulkAssignMutation.isPending && (
                <Loader2 className="mr-1.5 h-4 w-4 animate-spin" />
              )}
              Assign to {selected.size} project
              {selected.size === 1 ? '' : 's'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}
