'use client'

import { useState, useMemo } from 'react'
import Link from 'next/link'
import { trpc } from '@/lib/trpc/client'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Textarea } from '@/components/ui/textarea'
import { Badge } from '@/components/ui/badge'
import { Skeleton } from '@/components/ui/skeleton'
import { Checkbox } from '@/components/ui/checkbox'
import { Switch } from '@/components/ui/switch'
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import {
  Tabs,
  TabsContent,
  TabsList,
  TabsTrigger,
} from '@/components/ui/tabs'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from '@/components/ui/collapsible'
import {
  Send,
  Mail,
  Bell,
  Clock,
  Loader2,
  LayoutTemplate,
  AlertCircle,
  Inbox,
  CheckCircle2,
  Eye,
  Users,
  FolderOpen,
  XCircle,
  ArrowRight,
  ChevronDown,
  ChevronRight,
} from 'lucide-react'
import { toast } from 'sonner'
import { formatDate } from '@/lib/utils'

type RecipientType = 'ALL' | 'ROLE' | 'ROUND_JURY' | 'ROUND_APPLICANTS' | 'PROGRAM_TEAM' | 'USER'

const RECIPIENT_TYPE_OPTIONS: { value: RecipientType; label: string }[] = [
  { value: 'ALL', label: 'All Users' },
  { value: 'ROLE', label: 'By Role' },
  { value: 'ROUND_JURY', label: 'Round Jury' },
  { value: 'ROUND_APPLICANTS', label: 'Round Applicants' },
  { value: 'PROGRAM_TEAM', label: 'Program Team' },
  { value: 'USER', label: 'Specific User' },
]

const ROLES = ['JURY_MEMBER', 'MENTOR', 'OBSERVER', 'APPLICANT', 'PROGRAM_ADMIN']

const STATE_LABELS: Record<string, string> = {
  PENDING: 'Pending',
  IN_PROGRESS: 'Active',
  COMPLETED: 'Completed',
  PASSED: 'Passed',
  REJECTED: 'Rejected',
  WITHDRAWN: 'Withdrawn',
}

const STATE_BADGE_VARIANT: Record<string, 'default' | 'success' | 'destructive' | 'secondary'> = {
  PENDING: 'secondary',
  IN_PROGRESS: 'default',
  COMPLETED: 'default',
  PASSED: 'success',
  REJECTED: 'destructive',
  WITHDRAWN: 'secondary',
}

export default function MessagesPage() {
  const [recipientType, setRecipientType] = useState<RecipientType>('ALL')
  const [selectedRole, setSelectedRole] = useState('')
  const [roundIds, setRoundIds] = useState<string[]>([])
  const [selectedProgramId, setSelectedProgramId] = useState('')
  const [selectedUserId, setSelectedUserId] = useState('')
  const [subject, setSubject] = useState('')
  const [body, setBody] = useState('')
  const [selectedTemplateId, setSelectedTemplateId] = useState('')
  const [deliveryChannels, setDeliveryChannels] = useState<string[]>(['EMAIL', 'IN_APP'])
  const [linkType, setLinkType] = useState<'NONE' | 'MESSAGES' | 'LOGIN' | 'INVITE'>('MESSAGES')
  const [isScheduled, setIsScheduled] = useState(false)
  const [scheduledAt, setScheduledAt] = useState('')
  const [showPreview, setShowPreview] = useState(false)
  const [excludeRejected, setExcludeRejected] = useState(true)
  const [excludeWithdrawn, setExcludeWithdrawn] = useState(true)

  const utils = trpc.useUtils()

  // Fetch supporting data
  const { data: programs } = trpc.program.list.useQuery({ includeStages: true })
  const rounds = programs?.flatMap((p) =>
    ((p.stages ?? []) as Array<{ id: string; name: string; status: string }>).map((s: { id: string; name: string; status: string }) => ({ ...s, program: { name: p.name } }))
  ) || []
  const { data: templates } = trpc.message.listTemplates.useQuery()
  const { data: users } = trpc.user.list.useQuery(
    { page: 1, perPage: 100 },
    { enabled: recipientType === 'USER' }
  )

  // Fetch sent messages for history
  const { data: sentMessages, isLoading: loadingSent } = trpc.message.sent.useQuery(
    { page: 1, pageSize: 50 },
    { refetchInterval: 30_000 }
  )

  // Compute exclude states list
  const excludeStates = useMemo(() => {
    const states: string[] = []
    if (excludeRejected) states.push('REJECTED')
    if (excludeWithdrawn) states.push('WITHDRAWN')
    return states
  }, [excludeRejected, excludeWithdrawn])

  // Live recipient preview — fetches whenever selection changes
  const recipientPreview = trpc.message.previewRecipients.useQuery(
    {
      recipientType,
      recipientFilter: buildRecipientFilterValue(),
      roundIds: roundIds.length > 0 ? roundIds : undefined,
      excludeStates: recipientType === 'ROUND_APPLICANTS' ? excludeStates : undefined,
    },
    {
      enabled: recipientType === 'ROUND_APPLICANTS'
        ? roundIds.length > 0
        : recipientType === 'ROUND_JURY'
          ? roundIds.length > 0
          : recipientType === 'ROLE'
            ? !!selectedRole
            : recipientType === 'USER'
              ? !!selectedUserId
              : recipientType === 'PROGRAM_TEAM'
                ? !!selectedProgramId
                : recipientType === 'ALL',
    }
  )

  // Detailed recipient list (fetched on-demand when user expands section)
  const [showRecipientDetails, setShowRecipientDetails] = useState(false)
  const recipientDetails = trpc.message.listRecipientDetails.useQuery(
    {
      recipientType,
      recipientFilter: buildRecipientFilterValue(),
      roundIds: roundIds.length > 0 ? roundIds : undefined,
      excludeStates: recipientType === 'ROUND_APPLICANTS' ? excludeStates : undefined,
    },
    {
      enabled: showRecipientDetails && (
        recipientType === 'ROUND_APPLICANTS'
          ? roundIds.length > 0
          : recipientType === 'ROUND_JURY'
            ? roundIds.length > 0
            : recipientType === 'ROLE'
              ? !!selectedRole
              : recipientType === 'USER'
                ? !!selectedUserId
                : recipientType === 'PROGRAM_TEAM'
                  ? !!selectedProgramId
                  : recipientType === 'ALL'
      ),
    }
  )

  const emailPreview = trpc.message.previewEmail.useQuery(
    { subject, body },
    { enabled: showPreview && subject.length > 0 && body.length > 0 }
  )

  const sendTestMutation = trpc.message.sendTest.useMutation({
    onSuccess: (data) => toast.success(`Test email sent to ${data.to}`),
    onError: (e) => toast.error(e.message),
  })

  const sendMutation = trpc.message.send.useMutation({
    onSuccess: (data) => {
      const count = (data as Record<string, unknown>)?.recipientCount || ''
      toast.success(`Message sent successfully${count ? ` to ${count} recipients` : ''}`)
      resetForm()
      utils.message.sent.invalidate()
    },
    onError: (e) => toast.error(e.message),
  })

  const resetForm = () => {
    setSubject('')
    setBody('')
    setSelectedTemplateId('')
    setSelectedRole('')
    setRoundIds([])
    setSelectedProgramId('')
    setSelectedUserId('')
    setIsScheduled(false)
    setScheduledAt('')
    setLinkType('MESSAGES')
    setShowRecipientDetails(false)
  }

  const handleTemplateSelect = (templateId: string) => {
    setSelectedTemplateId(templateId)
    if (templateId && templateId !== '__none__' && templates) {
      const template = (templates as Array<Record<string, unknown>>).find(
        (t) => String(t.id) === templateId
      )
      if (template) {
        setSubject(String(template.subject || ''))
        setBody(String(template.body || ''))
      }
    }
  }

  const toggleChannel = (channel: string) => {
    setDeliveryChannels((prev) =>
      prev.includes(channel)
        ? prev.filter((c) => c !== channel)
        : [...prev, channel]
    )
  }

  function buildRecipientFilterValue(): unknown {
    switch (recipientType) {
      case 'ROLE':
        return selectedRole ? { role: selectedRole } : undefined
      case 'USER':
        return selectedUserId ? { userId: selectedUserId } : undefined
      case 'PROGRAM_TEAM':
        return selectedProgramId ? { programId: selectedProgramId } : undefined
      default:
        return undefined
    }
  }

  const getRecipientDescription = (): string => {
    switch (recipientType) {
      case 'ALL':
        return 'All platform users'
      case 'ROLE': {
        const roleLabel = selectedRole ? selectedRole.replace(/_/g, ' ') : ''
        return roleLabel ? `All ${roleLabel}s` : 'By Role (none selected)'
      }
      case 'ROUND_JURY': {
        if (roundIds.length === 0) return 'Stage Jury (none selected)'
        const selectedJuryRounds = rounds?.filter((r) => roundIds.includes(r.id))
        if (!selectedJuryRounds?.length) return 'Stage Jury'
        if (selectedJuryRounds.length === 1) {
          const s = selectedJuryRounds[0]
          return `Jury of ${s.program ? `${s.program.name} - ` : ''}${s.name}`
        }
        return `Jury across ${selectedJuryRounds.length} rounds`
      }
      case 'ROUND_APPLICANTS': {
        if (roundIds.length === 0) return 'Round Applicants (none selected)'
        const selectedAppRounds = rounds?.filter((r) => roundIds.includes(r.id))
        if (!selectedAppRounds?.length) return 'Round Applicants'
        if (selectedAppRounds.length === 1) {
          const ar = selectedAppRounds[0]
          return `Applicants in ${ar.program ? `${ar.program.name} - ` : ''}${ar.name}`
        }
        return `Applicants across ${selectedAppRounds.length} rounds`
      }
      case 'PROGRAM_TEAM': {
        if (!selectedProgramId) return 'Program Team (none selected)'
        const program = (programs as Array<{ id: string; name: string }> | undefined)?.find(
          (p) => p.id === selectedProgramId
        )
        return program ? `Team of ${program.name}` : 'Program Team'
      }
      case 'USER': {
        if (!selectedUserId) return 'Specific User (none selected)'
        const userList = (users as { users: Array<{ id: string; name: string | null; email: string }> } | undefined)?.users
        const user = userList?.find((u) => u.id === selectedUserId)
        return user ? (user.name || user.email) : 'Specific User'
      }
      default:
        return 'Unknown'
    }
  }

  const validateForm = (): boolean => {
    if (!subject.trim()) {
      toast.error('Subject is required')
      return false
    }
    if (!body.trim()) {
      toast.error('Message body is required')
      return false
    }
    if (deliveryChannels.length === 0) {
      toast.error('Select at least one delivery channel')
      return false
    }
    if (recipientType === 'ROLE' && !selectedRole) {
      toast.error('Please select a role')
      return false
    }
    if ((recipientType === 'ROUND_JURY' || recipientType === 'ROUND_APPLICANTS') && roundIds.length === 0) {
      toast.error('Please select at least one round')
      return false
    }
    if (recipientType === 'PROGRAM_TEAM' && !selectedProgramId) {
      toast.error('Please select a program')
      return false
    }
    if (recipientType === 'USER' && !selectedUserId) {
      toast.error('Please select a user')
      return false
    }
    return true
  }

  const handlePreview = () => {
    if (!validateForm()) return
    setShowPreview(true)
  }

  const handleActualSend = () => {
    sendMutation.mutate({
      recipientType,
      recipientFilter: buildRecipientFilterValue(),
      roundIds: roundIds.length > 0 ? roundIds : undefined,
      excludeStates: recipientType === 'ROUND_APPLICANTS' ? excludeStates : undefined,
      subject: subject.trim(),
      body: body.trim(),
      deliveryChannels,
      scheduledAt: isScheduled && scheduledAt ? new Date(scheduledAt).toISOString() : undefined,
      templateId: selectedTemplateId && selectedTemplateId !== '__none__' ? selectedTemplateId : undefined,
      linkType,
    })
    setShowPreview(false)
  }

  const preview = recipientPreview.data

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-semibold tracking-tight">Communication Hub</h1>
          <p className="text-muted-foreground">
            Send messages and notifications to platform users
          </p>
        </div>
        <Button variant="outline" asChild>
          <Link href="/admin/messages/templates">
            <LayoutTemplate className="mr-2 h-4 w-4" />
            Templates
          </Link>
        </Button>
      </div>

      <Tabs defaultValue="compose">
        <TabsList>
          <TabsTrigger value="compose">
            <Send className="mr-2 h-4 w-4" />
            Compose
          </TabsTrigger>
          <TabsTrigger value="history">
            <Inbox className="mr-2 h-4 w-4" />
            Sent History
          </TabsTrigger>
        </TabsList>

        <TabsContent value="compose" className="space-y-4 mt-4">
          <div className="grid gap-4 lg:grid-cols-3">
            {/* Left: Compose form */}
            <div className="lg:col-span-2 space-y-4">
              <Card>
                <CardHeader>
                  <CardTitle className="text-lg">Compose Message</CardTitle>
                  <CardDescription>
                    Send a message via email, in-app notifications, or both
                  </CardDescription>
                </CardHeader>
                <CardContent className="space-y-4">
                  {/* Recipient type */}
                  <div className="space-y-2">
                    <Label>Recipient Type</Label>
                    <Select
                      value={recipientType}
                      onValueChange={(v) => {
                        setRecipientType(v as RecipientType)
                        setSelectedRole('')
                        setRoundIds([])
                        setSelectedProgramId('')
                        setSelectedUserId('')
                      }}
                    >
                      <SelectTrigger>
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        {RECIPIENT_TYPE_OPTIONS.map((opt) => (
                          <SelectItem key={opt.value} value={opt.value}>
                            {opt.label}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>

                  {/* Conditional sub-filters */}
                  {recipientType === 'ROLE' && (
                    <div className="space-y-2">
                      <Label>Select Role</Label>
                      <Select value={selectedRole} onValueChange={setSelectedRole}>
                        <SelectTrigger>
                          <SelectValue placeholder="Choose a role..." />
                        </SelectTrigger>
                        <SelectContent>
                          {ROLES.map((role) => (
                            <SelectItem key={role} value={role}>
                              {role.replace(/_/g, ' ')}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>
                  )}

                  {(recipientType === 'ROUND_JURY' || recipientType === 'ROUND_APPLICANTS') && (
                    <div className="space-y-2">
                      <Label>Select Rounds</Label>
                      <div className="rounded-lg border p-3 space-y-2 max-h-48 overflow-y-auto">
                        {rounds?.length === 0 && (
                          <p className="text-sm text-muted-foreground">No rounds available</p>
                        )}
                        {rounds?.map((round) => {
                          const label = round.program ? `${round.program.name} - ${round.name}` : round.name
                          const isChecked = roundIds.includes(round.id)
                          const isActive = round.status === 'ROUND_ACTIVE'
                          return (
                            <div key={round.id} className={`flex items-center gap-2 ${!isActive ? 'opacity-60' : ''}`}>
                              <Checkbox
                                id={`round-${round.id}`}
                                checked={isChecked}
                                onCheckedChange={(checked) => {
                                  setRoundIds((prev) =>
                                    checked
                                      ? [...prev, round.id]
                                      : prev.filter((id) => id !== round.id)
                                  )
                                }}
                              />
                              <label htmlFor={`round-${round.id}`} className="text-sm cursor-pointer flex items-center gap-1.5">
                                {isActive && <span className="inline-block h-2 w-2 rounded-full bg-green-500 shrink-0" />}
                                {label}
                              </label>
                            </div>
                          )
                        })}
                      </div>
                      {roundIds.length > 0 && (
                        <p className="text-xs text-muted-foreground">
                          {roundIds.length} round{roundIds.length > 1 ? 's' : ''} selected
                        </p>
                      )}
                    </div>
                  )}

                  {/* Exclude filters for Round Applicants */}
                  {recipientType === 'ROUND_APPLICANTS' && roundIds.length > 0 && (
                    <div className="rounded-lg border p-3 space-y-2">
                      <Label className="text-sm font-medium">Exclude Project States</Label>
                      <div className="flex flex-wrap gap-4">
                        <div className="flex items-center gap-2">
                          <Checkbox
                            id="exclude-rejected"
                            checked={excludeRejected}
                            onCheckedChange={(v) => setExcludeRejected(!!v)}
                          />
                          <label htmlFor="exclude-rejected" className="text-sm cursor-pointer flex items-center gap-1.5">
                            <XCircle className="h-3.5 w-3.5 text-destructive" />
                            Exclude Rejected
                          </label>
                        </div>
                        <div className="flex items-center gap-2">
                          <Checkbox
                            id="exclude-withdrawn"
                            checked={excludeWithdrawn}
                            onCheckedChange={(v) => setExcludeWithdrawn(!!v)}
                          />
                          <label htmlFor="exclude-withdrawn" className="text-sm cursor-pointer flex items-center gap-1.5">
                            <XCircle className="h-3.5 w-3.5 text-muted-foreground" />
                            Exclude Withdrawn
                          </label>
                        </div>
                      </div>
                    </div>
                  )}

                  {recipientType === 'PROGRAM_TEAM' && (
                    <div className="space-y-2">
                      <Label>Select Program</Label>
                      <Select value={selectedProgramId} onValueChange={setSelectedProgramId}>
                        <SelectTrigger>
                          <SelectValue placeholder="Choose a program..." />
                        </SelectTrigger>
                        <SelectContent>
                          {(programs as Array<{ id: string; name: string }> | undefined)?.map((prog) => (
                            <SelectItem key={prog.id} value={prog.id}>
                              {prog.name}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>
                  )}

                  {recipientType === 'USER' && (
                    <div className="space-y-2">
                      <Label>Select User</Label>
                      <Select value={selectedUserId} onValueChange={setSelectedUserId}>
                        <SelectTrigger>
                          <SelectValue placeholder="Choose a user..." />
                        </SelectTrigger>
                        <SelectContent>
                          {(() => {
                            const userList = (users as { users: Array<{ id: string; name: string | null; email: string; role: string }> } | undefined)?.users
                            if (!userList) return null

                            const grouped = userList.reduce<Record<string, typeof userList>>((acc, u) => {
                              const role = u.role || 'OTHER'
                              if (!acc[role]) acc[role] = []
                              acc[role].push(u)
                              return acc
                            }, {})

                            const roleLabels: Record<string, string> = {
                              SUPER_ADMIN: 'Super Admins',
                              PROGRAM_ADMIN: 'Program Admins',
                              JURY_MEMBER: 'Jury Members',
                              MENTOR: 'Mentors',
                              OBSERVER: 'Observers',
                              APPLICANT: 'Applicants',
                              OTHER: 'Other',
                            }

                            const roleOrder = ['SUPER_ADMIN', 'PROGRAM_ADMIN', 'JURY_MEMBER', 'MENTOR', 'OBSERVER', 'APPLICANT', 'OTHER']

                            return roleOrder
                              .filter((role) => grouped[role]?.length)
                              .map((role) => (
                                <SelectGroup key={role}>
                                  <SelectLabel>{roleLabels[role] || role}</SelectLabel>
                                  {grouped[role]
                                    .sort((a, b) => (a.name || a.email).localeCompare(b.name || b.email))
                                    .map((u) => (
                                      <SelectItem key={u.id} value={u.id}>
                                        {u.name || u.email}
                                      </SelectItem>
                                    ))}
                                </SelectGroup>
                              ))
                          })()}
                        </SelectContent>
                      </Select>
                    </div>
                  )}

                  {recipientType === 'ALL' && (
                    <div className="flex items-center gap-2 rounded-lg bg-amber-500/10 p-3 text-amber-700">
                      <AlertCircle className="h-4 w-4 shrink-0" />
                      <p className="text-sm">
                        This message will be sent to all platform users.
                      </p>
                    </div>
                  )}

                  {/* Template selector */}
                  {templates && (templates as unknown[]).length > 0 && (
                    <div className="space-y-2">
                      <Label>Template (optional)</Label>
                      <Select value={selectedTemplateId} onValueChange={handleTemplateSelect}>
                        <SelectTrigger>
                          <SelectValue placeholder="Load from template..." />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="__none__">No template</SelectItem>
                          {(templates as Array<Record<string, unknown>>).map((t) => (
                            <SelectItem key={String(t.id)} value={String(t.id)}>
                              {String(t.name)}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>
                  )}

                  {/* Subject */}
                  <div className="space-y-2">
                    <Label>Subject</Label>
                    <Input
                      placeholder="Message subject..."
                      value={subject}
                      onChange={(e) => setSubject(e.target.value)}
                    />
                  </div>

                  {/* Body */}
                  <div className="space-y-2">
                    <div className="flex items-center justify-between">
                      <Label>Message Body</Label>
                      <span className="text-xs text-muted-foreground">
                        Variables: {'{{projectName}}'}, {'{{userName}}'}, {'{{deadline}}'}, {'{{roundName}}'}, {'{{programName}}'}
                      </span>
                    </div>
                    <Textarea
                      placeholder="Write your message..."
                      value={body}
                      onChange={(e) => setBody(e.target.value)}
                      rows={6}
                    />
                  </div>

                  {/* Delivery channels */}
                  <div className="space-y-2">
                    <Label>Delivery Channels</Label>
                    <div className="flex items-center gap-6">
                      <div className="flex items-center gap-2">
                        <Checkbox
                          id="channel-email"
                          checked={deliveryChannels.includes('EMAIL')}
                          onCheckedChange={() => toggleChannel('EMAIL')}
                        />
                        <label htmlFor="channel-email" className="text-sm cursor-pointer flex items-center gap-1">
                          <Mail className="h-3 w-3" />
                          Email
                        </label>
                      </div>
                      <div className="flex items-center gap-2">
                        <Checkbox
                          id="channel-inapp"
                          checked={deliveryChannels.includes('IN_APP')}
                          onCheckedChange={() => toggleChannel('IN_APP')}
                        />
                        <label htmlFor="channel-inapp" className="text-sm cursor-pointer flex items-center gap-1">
                          <Bell className="h-3 w-3" />
                          In-App
                        </label>
                      </div>
                    </div>
                  </div>

                  {/* Link in Email */}
                  {deliveryChannels.includes('EMAIL') && (
                    <div className="space-y-2">
                      <Label>Email Link Button</Label>
                      <Select
                        value={linkType}
                        onValueChange={(v) => setLinkType(v as typeof linkType)}
                      >
                        <SelectTrigger>
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="NONE">No link button</SelectItem>
                          <SelectItem value="MESSAGES">Link to Messages</SelectItem>
                          <SelectItem value="LOGIN">Link to Login</SelectItem>
                          <SelectItem value="INVITE">Invite / Accept link (for new members)</SelectItem>
                        </SelectContent>
                      </Select>
                      <p className="text-xs text-muted-foreground">
                        {linkType === 'NONE'
                          ? 'No button will appear in the email.'
                          : linkType === 'MESSAGES'
                            ? 'Recipients see a "View Details" button linking to their messages inbox.'
                            : linkType === 'LOGIN'
                              ? 'Recipients see a button linking to the login page.'
                              : 'New members get their personal invite link; existing members get the login page.'}
                      </p>
                    </div>
                  )}

                  {/* Schedule */}
                  <div className="space-y-2">
                    <div className="flex items-center gap-2">
                      <Switch
                        id="schedule-toggle"
                        checked={isScheduled}
                        onCheckedChange={setIsScheduled}
                      />
                      <label htmlFor="schedule-toggle" className="text-sm cursor-pointer flex items-center gap-1">
                        <Clock className="h-3 w-3" />
                        Schedule for later
                      </label>
                    </div>
                    {isScheduled && (
                      <Input
                        type="datetime-local"
                        value={scheduledAt}
                        onChange={(e) => setScheduledAt(e.target.value)}
                      />
                    )}
                  </div>

                  {/* Preview button */}
                  <div className="flex justify-end">
                    <Button onClick={handlePreview} disabled={sendMutation.isPending}>
                      {sendMutation.isPending ? (
                        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                      ) : (
                        <Eye className="mr-2 h-4 w-4" />
                      )}
                      {isScheduled ? 'Preview & Schedule' : 'Preview & Send'}
                    </Button>
                  </div>
                </CardContent>
              </Card>
            </div>

            {/* Right sidebar: Recipient Summary */}
            <div className="space-y-4">
              <Card>
                <CardHeader className="pb-3">
                  <CardTitle className="text-sm flex items-center gap-2">
                    <Users className="h-4 w-4 text-blue-500" />
                    Recipient Summary
                  </CardTitle>
                </CardHeader>
                <CardContent>
                  {recipientPreview.isLoading ? (
                    <div className="space-y-2">
                      <Skeleton className="h-5 w-32" />
                      <Skeleton className="h-4 w-24" />
                    </div>
                  ) : preview ? (
                    <div className="space-y-3">
                      <div className="text-sm text-muted-foreground">
                        {getRecipientDescription()}
                      </div>

                      {/* Stats */}
                      <div className="grid grid-cols-2 gap-3">
                        {preview.totalProjects > 0 && (
                          <div className="rounded-lg border p-3 text-center">
                            <div className="flex items-center justify-center gap-1.5 mb-1">
                              <FolderOpen className="h-3.5 w-3.5 text-muted-foreground" />
                              <span className="text-xs text-muted-foreground">Projects</span>
                            </div>
                            <p className="text-xl font-bold tabular-nums">{preview.totalProjects}</p>
                          </div>
                        )}
                        <div className={`rounded-lg border p-3 text-center ${preview.totalProjects > 0 ? '' : 'col-span-2'}`}>
                          <div className="flex items-center justify-center gap-1.5 mb-1">
                            <Users className="h-3.5 w-3.5 text-muted-foreground" />
                            <span className="text-xs text-muted-foreground">Recipients</span>
                          </div>
                          <p className="text-xl font-bold tabular-nums">{preview.totalApplicants}</p>
                        </div>
                      </div>

                      {/* State breakdown for Round Applicants */}
                      {recipientType === 'ROUND_APPLICANTS' && Object.keys(preview.stateBreakdown).length > 0 && (
                        <div className="space-y-2">
                          <p className="text-xs font-medium text-muted-foreground uppercase tracking-wider">
                            Projects by Status
                          </p>
                          <div className="space-y-1.5">
                            {Object.entries(preview.stateBreakdown)
                              .sort(([a], [b]) => {
                                const order = ['IN_PROGRESS', 'PENDING', 'COMPLETED', 'PASSED', 'REJECTED', 'WITHDRAWN']
                                return order.indexOf(a) - order.indexOf(b)
                              })
                              .map(([state, count]) => {
                                const isExcluded = excludeStates.includes(state)
                                return (
                                  <div
                                    key={state}
                                    className={`flex items-center justify-between rounded-md px-2.5 py-1.5 text-sm ${
                                      isExcluded ? 'bg-muted/50 opacity-50 line-through' : 'bg-muted/30'
                                    }`}
                                  >
                                    <div className="flex items-center gap-2">
                                      <Badge
                                        variant={STATE_BADGE_VARIANT[state] || 'secondary'}
                                        className="text-[10px] px-1.5 py-0"
                                      >
                                        {STATE_LABELS[state] || state}
                                      </Badge>
                                      {isExcluded && (
                                        <span className="text-[10px] text-muted-foreground">(excluded)</span>
                                      )}
                                    </div>
                                    <span className="font-semibold tabular-nums">{count}</span>
                                  </div>
                                )
                              })}
                          </div>

                          {/* Included vs excluded summary */}
                          {excludeStates.length > 0 && (
                            <div className="rounded-lg bg-blue-500/5 border border-blue-200/50 p-2.5 mt-2">
                              <p className="text-xs text-blue-700">
                                Sending to <span className="font-semibold">{preview.totalApplicants}</span> applicants
                                {' '}across{' '}
                                <span className="font-semibold">
                                  {preview.totalProjects - Object.entries(preview.stateBreakdown)
                                    .filter(([s]) => excludeStates.includes(s))
                                    .reduce((sum, [, c]) => sum + c, 0)}
                                </span>{' '}
                                projects (excluding{' '}
                                {excludeStates.map((s) => STATE_LABELS[s] || s).join(' & ').toLowerCase()}).
                              </p>
                            </div>
                          )}
                        </div>
                      )}

                      {/* Expandable recipient details */}
                      <RecipientDetailsList
                        open={showRecipientDetails}
                        onOpenChange={setShowRecipientDetails}
                        data={recipientDetails.data}
                        isLoading={recipientDetails.isLoading}
                        recipientType={recipientType}
                      />
                    </div>
                  ) : (
                    <p className="text-sm text-muted-foreground">
                      Select a recipient type{recipientType !== 'ALL' ? ' and filter' : ''} to see a summary.
                    </p>
                  )}
                </CardContent>
              </Card>
            </div>
          </div>
        </TabsContent>

        <TabsContent value="history" className="mt-4">
          <Card>
            <CardHeader>
              <CardTitle className="text-lg">Sent Messages</CardTitle>
              <CardDescription>
                Recent messages sent through the platform
              </CardDescription>
            </CardHeader>
            <CardContent>
              {loadingSent ? (
                <div className="space-y-3">
                  {[1, 2, 3].map((i) => (
                    <div key={i} className="flex items-center gap-4">
                      <Skeleton className="h-4 w-48" />
                      <Skeleton className="h-6 w-24" />
                      <Skeleton className="h-4 w-32 ml-auto" />
                    </div>
                  ))}
                </div>
              ) : sentMessages && sentMessages.items.length > 0 ? (
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead>Subject</TableHead>
                      <TableHead className="hidden md:table-cell">Recipients</TableHead>
                      <TableHead className="hidden md:table-cell">Channels</TableHead>
                      <TableHead className="hidden lg:table-cell">Status</TableHead>
                      <TableHead className="text-right">Date</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {sentMessages.items.map((msg: any) => {
                      const channels = (msg.deliveryChannels as string[]) || []
                      const recipientCount = msg._count?.recipients ?? 0
                      const isSent = !!msg.sentAt

                      return (
                        <TableRow key={msg.id}>
                          <TableCell>
                            <span className="font-medium">
                              {msg.subject || 'No subject'}
                            </span>
                          </TableCell>
                          <TableCell className="hidden md:table-cell text-sm text-muted-foreground">
                            {msg.recipientType === 'ALL'
                              ? 'All users'
                              : msg.recipientType === 'ROLE'
                                ? `By role`
                                : msg.recipientType === 'ROUND_JURY'
                                  ? 'Round jury'
                                  : msg.recipientType === 'ROUND_APPLICANTS'
                                    ? 'Round applicants'
                                    : msg.recipientType === 'USER'
                                      ? `${recipientCount || 1} user${recipientCount > 1 ? 's' : ''}`
                                      : msg.recipientType}
                            {recipientCount > 0 && ` (${recipientCount})`}
                          </TableCell>
                          <TableCell className="hidden md:table-cell">
                            <div className="flex gap-1">
                              {channels.includes('EMAIL') && (
                                <Badge variant="outline" className="text-xs">
                                  <Mail className="mr-1 h-3 w-3" />Email
                                </Badge>
                              )}
                              {channels.includes('IN_APP') && (
                                <Badge variant="outline" className="text-xs">
                                  <Bell className="mr-1 h-3 w-3" />In-App
                                </Badge>
                              )}
                            </div>
                          </TableCell>
                          <TableCell className="hidden lg:table-cell">
                            {isSent ? (
                              <Badge variant="secondary" className="text-xs">
                                <CheckCircle2 className="mr-1 h-3 w-3" />
                                Sent
                              </Badge>
                            ) : msg.scheduledAt ? (
                              <Badge variant="default" className="text-xs">
                                <Clock className="mr-1 h-3 w-3" />
                                Scheduled
                              </Badge>
                            ) : (
                              <Badge variant="outline" className="text-xs">
                                Draft
                              </Badge>
                            )}
                          </TableCell>
                          <TableCell className="text-right text-sm text-muted-foreground">
                            {msg.sentAt
                              ? formatDate(msg.sentAt)
                              : msg.scheduledAt
                                ? formatDate(msg.scheduledAt)
                                : ''}
                          </TableCell>
                        </TableRow>
                      )
                    })}
                  </TableBody>
                </Table>
              ) : (
                <div className="flex flex-col items-center justify-center py-12 text-center">
                  <Inbox className="h-12 w-12 text-muted-foreground/50" />
                  <p className="mt-2 font-medium">No messages yet</p>
                  <p className="text-sm text-muted-foreground">
                    Sent messages will appear here.
                  </p>
                </div>
              )}
            </CardContent>
          </Card>
        </TabsContent>
      </Tabs>

      {/* Preview & Send Dialog */}
      <Dialog open={showPreview} onOpenChange={setShowPreview}>
        <DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle className="text-xl">Review & Send</DialogTitle>
            <DialogDescription>Verify everything looks correct before sending</DialogDescription>
          </DialogHeader>

          <div className="grid gap-6 md:grid-cols-5">
            {/* Left: Message details */}
            <div className="md:col-span-3 space-y-4">
              <div>
                <p className="text-xs font-medium text-muted-foreground uppercase tracking-wider">Subject</p>
                <p className="text-base font-semibold mt-1">{subject}</p>
              </div>

              <div>
                <p className="text-xs font-medium text-muted-foreground uppercase tracking-wider mb-2">Email Preview</p>
                <div className="rounded-lg border overflow-hidden bg-gray-50">
                  {emailPreview.data?.html ? (
                    <iframe
                      srcDoc={emailPreview.data.html}
                      sandbox="allow-same-origin"
                      className="w-full h-[400px] border-0"
                      title="Email Preview"
                    />
                  ) : (
                    <div className="p-4">
                      <p className="text-sm whitespace-pre-wrap">{body}</p>
                    </div>
                  )}
                </div>
              </div>
            </div>

            {/* Right: Recipient & delivery summary */}
            <div className="md:col-span-2 space-y-4">
              <div className="rounded-lg border p-4 space-y-3">
                <p className="text-xs font-medium text-muted-foreground uppercase tracking-wider">Recipients</p>
                <p className="text-sm font-medium">{getRecipientDescription()}</p>

                {preview && (
                  <div className="space-y-2">
                    {preview.totalProjects > 0 && (
                      <div className="flex items-center justify-between text-sm">
                        <span className="text-muted-foreground flex items-center gap-1.5">
                          <FolderOpen className="h-3.5 w-3.5" />
                          Projects
                        </span>
                        <span className="font-semibold tabular-nums">
                          {preview.totalProjects - Object.entries(preview.stateBreakdown)
                            .filter(([s]) => excludeStates.includes(s))
                            .reduce((sum, [, c]) => sum + c, 0)}
                          {excludeStates.length > 0 && (
                            <span className="text-muted-foreground font-normal"> / {preview.totalProjects}</span>
                          )}
                        </span>
                      </div>
                    )}
                    <div className="flex items-center justify-between text-sm">
                      <span className="text-muted-foreground flex items-center gap-1.5">
                        <Users className="h-3.5 w-3.5" />
                        Applicants
                      </span>
                      <span className="font-semibold tabular-nums">{preview.totalApplicants}</span>
                    </div>

                    {/* State breakdown in preview */}
                    {recipientType === 'ROUND_APPLICANTS' && Object.keys(preview.stateBreakdown).length > 0 && (
                      <div className="pt-2 border-t space-y-1">
                        {Object.entries(preview.stateBreakdown)
                          .sort(([a], [b]) => {
                            const order = ['IN_PROGRESS', 'PENDING', 'COMPLETED', 'PASSED', 'REJECTED', 'WITHDRAWN']
                            return order.indexOf(a) - order.indexOf(b)
                          })
                          .map(([state, count]) => {
                            const isExcluded = excludeStates.includes(state)
                            return (
                              <div
                                key={state}
                                className={`flex items-center justify-between text-xs ${isExcluded ? 'opacity-40 line-through' : ''}`}
                              >
                                <Badge variant={STATE_BADGE_VARIANT[state] || 'secondary'} className="text-[10px] px-1.5 py-0">
                                  {STATE_LABELS[state] || state}
                                </Badge>
                                <span className="tabular-nums">{count} projects</span>
                              </div>
                            )
                          })}
                      </div>
                    )}
                  </div>
                )}
              </div>

              <div className="rounded-lg border p-4 space-y-2">
                <p className="text-xs font-medium text-muted-foreground uppercase tracking-wider">Delivery</p>
                <div className="flex flex-wrap gap-1.5">
                  {deliveryChannels.includes('EMAIL') && (
                    <Badge variant="outline" className="text-xs">
                      <Mail className="mr-1 h-3 w-3" />
                      Email
                    </Badge>
                  )}
                  {deliveryChannels.includes('IN_APP') && (
                    <Badge variant="outline" className="text-xs">
                      <Bell className="mr-1 h-3 w-3" />
                      In-App
                    </Badge>
                  )}
                </div>
                {isScheduled && scheduledAt && (
                  <div className="flex items-center gap-1.5 text-sm text-muted-foreground mt-1">
                    <Clock className="h-3.5 w-3.5" />
                    Scheduled: {formatDate(new Date(scheduledAt))}
                  </div>
                )}
                {deliveryChannels.includes('EMAIL') && (
                  <p className="text-xs text-muted-foreground mt-1">
                    Link: {linkType === 'NONE' ? 'None' : linkType === 'MESSAGES' ? 'Messages inbox' : linkType === 'LOGIN' ? 'Login page' : 'Invite / Accept link'}
                  </p>
                )}
              </div>
            </div>
          </div>

          <DialogFooter className="flex-col sm:flex-row gap-2 mt-4 border-t pt-4">
            <Button
              variant="ghost"
              size="sm"
              onClick={() => sendTestMutation.mutate({ subject, body })}
              disabled={sendTestMutation.isPending}
              className="sm:mr-auto"
            >
              {sendTestMutation.isPending ? (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              ) : (
                <Mail className="mr-2 h-4 w-4" />
              )}
              Send Test to Me
            </Button>
            <Button variant="outline" onClick={() => setShowPreview(false)}>
              Back to Edit
            </Button>
            <Button onClick={handleActualSend} disabled={sendMutation.isPending} size="lg">
              {sendMutation.isPending ? (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              ) : (
                <Send className="mr-2 h-4 w-4" />
              )}
              {isScheduled ? 'Confirm & Schedule' : `Send to ${preview?.totalApplicants ?? '...'} Recipients`}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}

// =============================================================================
// Expandable recipient details
// =============================================================================

type RecipientDetailsData = {
  type: 'projects' | 'jurors' | 'users'
  projects: Array<{
    id: string
    title: string
    state: string
    roundId?: string
    roundName?: string
    members: Array<{ id: string; name: string | null; email: string }>
  }>
  users: Array<{
    id: string
    name: string | null
    email: string
    projectCount?: number
    projectNames?: string[]
    projectName?: string | null
    role?: string
    roundNames?: string[]
  }>
}

function RecipientDetailsList({
  open,
  onOpenChange,
  data,
  isLoading,
  recipientType,
}: {
  open: boolean
  onOpenChange: (open: boolean) => void
  data?: RecipientDetailsData
  isLoading: boolean
  recipientType: string
}) {
  return (
    <Collapsible open={open} onOpenChange={onOpenChange}>
      <CollapsibleTrigger className="flex items-center gap-1.5 text-xs font-medium text-muted-foreground hover:text-foreground transition-colors w-full pt-2">
        {open ? <ChevronDown className="h-3 w-3" /> : <ChevronRight className="h-3 w-3" />}
        View Recipients
      </CollapsibleTrigger>
      <CollapsibleContent>
        <div className="mt-2 max-h-[300px] overflow-y-auto rounded-md border bg-muted/20 p-2 space-y-1">
          {isLoading ? (
            <div className="space-y-2 p-1">
              {[1, 2, 3].map((i) => (
                <Skeleton key={i} className="h-4 w-full" />
              ))}
            </div>
          ) : !data || (data.projects.length === 0 && data.users.length === 0) ? (
            <p className="text-xs text-muted-foreground p-1">No recipients found.</p>
          ) : data.type === 'projects' ? (
            // ROUND_APPLICANTS: projects grouped by round (if multi-round)
            (() => {
              const roundGroups = new Map<string, { roundName: string; projects: typeof data.projects }>()
              for (const project of data.projects) {
                const key = project.roundId || '_unknown'
                const existing = roundGroups.get(key)
                if (existing) {
                  existing.projects.push(project)
                } else {
                  roundGroups.set(key, {
                    roundName: project.roundName || 'Unknown Round',
                    projects: [project],
                  })
                }
              }
              const groups = Array.from(roundGroups.values())
              const isMultiRound = groups.length > 1
              return groups.map((group) => (
                <div key={group.roundName}>
                  {isMultiRound && (
                    <div className="sticky top-0 bg-muted/60 backdrop-blur-sm px-2 py-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground border-b mb-1">
                      {group.roundName} ({group.projects.length})
                    </div>
                  )}
                  {group.projects.map((project) => (
                    <ProjectRecipientRow key={`${project.roundId}-${project.id}`} project={project} />
                  ))}
                </div>
              ))
            })()
          ) : data.type === 'jurors' ? (
            // ROUND_JURY: jurors with project counts and round info
            data.users.map((user) => (
              <div key={user.id} className="flex items-center justify-between rounded px-2 py-1.5 text-xs hover:bg-muted/50">
                <div className="min-w-0">
                  <Link
                    href={`/admin/members/${user.id}`}
                    className="font-medium hover:underline text-primary truncate block"
                  >
                    {user.name || user.email}
                  </Link>
                  <span className="text-muted-foreground">
                    {user.projectCount !== undefined && (
                      <>{user.projectCount} project{user.projectCount !== 1 ? 's' : ''} assigned</>
                    )}
                    {user.roundNames && user.roundNames.length > 1 && (
                      <> &middot; {user.roundNames.length} rounds</>
                    )}
                  </span>
                </div>
              </div>
            ))
          ) : (
            // ALL, ROLE, USER, PROGRAM_TEAM: plain user list
            data.users.map((user) => (
              <div key={user.id} className="flex items-center justify-between rounded px-2 py-1.5 text-xs hover:bg-muted/50">
                <div className="min-w-0">
                  <Link
                    href={`/admin/members/${user.id}`}
                    className="font-medium hover:underline text-primary truncate block"
                  >
                    {user.name || user.email}
                  </Link>
                  {user.projectName && (
                    <span className="text-muted-foreground truncate block">{user.projectName}</span>
                  )}
                </div>
                {user.role && (
                  <Badge variant="outline" className="text-[10px] px-1.5 py-0 shrink-0 ml-2">
                    {user.role.replace(/_/g, ' ')}
                  </Badge>
                )}
              </div>
            ))
          )}
        </div>
      </CollapsibleContent>
    </Collapsible>
  )
}

function ProjectRecipientRow({ project }: {
  project: {
    id: string
    title: string
    state: string
    roundId?: string
    roundName?: string
    members: Array<{ id: string; name: string | null; email: string }>
  }
}) {
  const [open, setOpen] = useState(false)

  return (
    <Collapsible open={open} onOpenChange={setOpen}>
      <CollapsibleTrigger className="flex items-center justify-between w-full rounded px-2 py-1.5 text-xs hover:bg-muted/50">
        <div className="flex items-center gap-1.5 min-w-0">
          {open ? <ChevronDown className="h-3 w-3 shrink-0" /> : <ChevronRight className="h-3 w-3 shrink-0" />}
          <span className="font-medium truncate">{project.title}</span>
        </div>
        <div className="flex items-center gap-1.5 shrink-0 ml-2">
          <Badge variant={STATE_BADGE_VARIANT[project.state] || 'secondary'} className="text-[10px] px-1.5 py-0">
            {STATE_LABELS[project.state] || project.state}
          </Badge>
          <span className="text-muted-foreground">{project.members.length}</span>
        </div>
      </CollapsibleTrigger>
      <CollapsibleContent>
        <div className="ml-5 space-y-0.5 pb-1">
          {project.members.map((member) => (
            <Link
              key={member.id}
              href={`/admin/members/${member.id}`}
              className="block text-xs px-2 py-0.5 text-primary hover:underline truncate"
            >
              {member.name || member.email}
            </Link>
          ))}
        </div>
      </CollapsibleContent>
    </Collapsible>
  )
}
