"use client";

import { useState, useTransition, useCallback, useEffect, useRef } from "react";
import { useRouter } from "next/navigation";
import Image from "next/image";
import Link from "next/link";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { cn } from "@/lib/utils";
import { updateShotNotes, bulkUpdateDueDates, toggleKeyShot } from "@/actions/shots";
import { useToast } from "@/components/ui/use-toast";
import {
  Film,
  Clock,
  CheckCircle2,
  AlertCircle,
  Calendar,
  CalendarDays,
  ChevronDown,
  ChevronRight,
  Loader2,
  X,
  ShieldCheck,
  Eye,
  Star,
} from "lucide-react";
import { format } from "date-fns";

type ShotRow = {
  id: string;
  shotCode: string;
  scene: string;
  episode: string | null;
  shotNumber: number;
  status: string;
  priority: string;
  dueDate: Date | string | null;
  thumbnailUrl: string | null;
  notes: string | null;
  description: string | null;
  isKeyShot: boolean;
  artist: { id: string; name: string | null; image: string | null; email: string } | null;
};

interface Project {
  id: string;
  name: string;
  code: string;
  projectType: string;
}

interface ShotStatusClientProps {
  projects: Project[];
  selectedProjectId: string | null;
  selectedProject: Project | null;
  shots: ShotRow[];
  episodeDueDates: { episode: string; dueDate: Date | string }[];
  canManage: boolean;
}

const SCROLL_KEY = 'shot-status-scroll';

const STATUS_CONFIG: Record<string, { label: string; color: string; icon: React.ElementType }> = {
  WAITING:          { label: "Waiting",           color: "bg-zinc-500/10 text-zinc-400 border-zinc-500/20",       icon: Clock },
  IN_PROGRESS:      { label: "In Progress",       color: "bg-blue-500/10 text-blue-400 border-blue-500/20",       icon: Film },
  INTERNAL_REVIEW:  { label: "Internal Review",   color: "bg-purple-500/10 text-purple-400 border-purple-500/20", icon: AlertCircle },
  READY_FOR_CLIENT: { label: "Ready for Client",  color: "bg-sky-500/10 text-sky-400 border-sky-500/20",           icon: ShieldCheck },
  CLIENT_REVIEW:    { label: "Client Review",     color: "bg-indigo-500/10 text-indigo-400 border-indigo-500/20", icon: Eye },
  REVISIONS:        { label: "Revisions",         color: "bg-orange-500/10 text-orange-400 border-orange-500/20", icon: AlertCircle },
  COMPLETE:         { label: "Complete",          color: "bg-emerald-500/10 text-emerald-400 border-emerald-500/20", icon: CheckCircle2 },
};

// ── IndeterminateCheckbox ──────────────────────────────────────────────────────

function IndeterminateCheckbox({
  checked,
  indeterminate,
  onChange,
  className,
}: {
  checked: boolean;
  indeterminate?: boolean;
  onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
  className?: string;
}) {
  const ref = useRef<HTMLInputElement>(null);
  useEffect(() => {
    if (ref.current) ref.current.indeterminate = !!indeterminate;
  }, [indeterminate]);
  return (
    <input
      ref={ref}
      type="checkbox"
      checked={checked}
      onChange={onChange}
      className={cn("cursor-pointer accent-blue-500 w-3.5 h-3.5", className)}
    />
  );
}

// ── BulkDueDateDialog ─────────────────────────────────────────────────────────

function BulkDueDateDialog({
  open,
  onClose,
  onApply,
  count,
}: {
  open: boolean;
  onClose: () => void;
  onApply: (date: string, includeTasks: boolean) => Promise<void>;
  count: number;
}) {
  const [date, setDate] = useState("");
  const [includeTasks, setIncludeTasks] = useState(false);
  const [isPending, startTransition] = useTransition();

  useEffect(() => {
    if (open) {
      setDate("");
      setIncludeTasks(false);
    }
  }, [open]);

  const handleApply = () => {
    if (!date) return;
    startTransition(async () => {
      await onApply(date, includeTasks);
    });
  };

  return (
    <Dialog open={open} onOpenChange={(o) => { if (!o && !isPending) onClose(); }}>
      <DialogContent className="sm:max-w-sm">
        <DialogHeader>
          <DialogTitle>Change Due Date</DialogTitle>
        </DialogHeader>

        <p className="text-sm text-zinc-400 -mt-1">
          Applying to <span className="text-white font-medium">{count}</span>{" "}
          shot{count !== 1 ? "s" : ""}
        </p>

        <div className="space-y-5 pt-1">
          <div className="space-y-1.5">
            <label className="text-xs font-medium text-zinc-400">New due date</label>
            <input
              type="date"
              value={date}
              onChange={(e) => setDate(e.target.value)}
              className="w-full rounded-md border border-zinc-700 bg-zinc-900 px-3 py-2 text-sm text-zinc-100 [color-scheme:dark] focus:border-zinc-500 focus:outline-none focus:ring-1 focus:ring-zinc-500"
            />
          </div>

          <div className="space-y-2">
            <label className="text-xs font-medium text-zinc-400">Apply to</label>
            <div className="space-y-2.5">
              <label className="flex items-center gap-2.5 cursor-pointer">
                <input
                  type="radio"
                  name="bulk-scope"
                  checked={!includeTasks}
                  onChange={() => setIncludeTasks(false)}
                  className="accent-blue-500 cursor-pointer"
                />
                <span className="text-sm text-zinc-200">Shots only</span>
              </label>
              <label className="flex items-center gap-2.5 cursor-pointer">
                <input
                  type="radio"
                  name="bulk-scope"
                  checked={includeTasks}
                  onChange={() => setIncludeTasks(true)}
                  className="accent-blue-500 cursor-pointer"
                />
                <span className="text-sm text-zinc-200">Shots and their tasks</span>
              </label>
            </div>
          </div>
        </div>

        <DialogFooter className="mt-2">
          <Button variant="ghost" onClick={onClose} disabled={isPending}>
            Cancel
          </Button>
          <Button onClick={handleApply} disabled={!date || isPending}>
            {isPending && <Loader2 className="h-3.5 w-3.5 mr-1.5 animate-spin" />}
            Apply
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

// ── NotesCell ─────────────────────────────────────────────────────────────────

function NotesCell({
  shot,
  canManage,
}: {
  shot: ShotRow;
  canManage: boolean;
}) {
  const [value, setValue] = useState(shot.notes ?? "");
  const [saved, setSaved] = useState(true);
  const [isPending, startTransition] = useTransition();
  const { toast } = useToast();

  const handleBlur = useCallback(() => {
    if (value === (shot.notes ?? "")) return;
    startTransition(async () => {
      try {
        await updateShotNotes(shot.id, value);
        setSaved(true);
        toast({ title: "Notes saved" });
      } catch {
        toast({ title: "Failed to save notes", variant: "destructive" });
      }
    });
  }, [value, shot.id, shot.notes, toast]);

  if (!canManage) {
    return (
      <span className="text-sm text-zinc-400 whitespace-pre-wrap">
        {shot.notes ?? <span className="italic text-zinc-600">—</span>}
      </span>
    );
  }

  return (
    <div className="relative">
      <Textarea
        value={value}
        onChange={(e) => { setValue(e.target.value); setSaved(false); }}
        onBlur={handleBlur}
        placeholder="Add notes..."
        className="min-h-[60px] text-sm resize-none bg-zinc-900 border-zinc-700 focus:border-zinc-500 text-zinc-200 placeholder:text-zinc-600"
        rows={2}
      />
      {isPending && (
        <Loader2 className="absolute bottom-2 right-2 h-3 w-3 animate-spin text-zinc-500" />
      )}
      {!isPending && !saved && (
        <span className="absolute bottom-1.5 right-2 text-[10px] text-zinc-500">unsaved</span>
      )}
    </div>
  );
}

// ── KeyShotToggle ─────────────────────────────────────────────────────────────

function KeyShotToggle({ shot }: { shot: ShotRow }) {
  const [optimistic, setOptimistic] = useState(shot.isKeyShot);
  const [isPending, startTransition] = useTransition();
  const { toast } = useToast();

  const handle = () => {
    const next = !optimistic;
    setOptimistic(next);
    startTransition(async () => {
      try {
        await toggleKeyShot(shot.id, next);
      } catch {
        setOptimistic(!next);
        toast({ title: "Failed to update key shot", variant: "destructive" });
      }
    });
  };

  return (
    <button
      type="button"
      role="switch"
      aria-checked={optimistic}
      aria-label={optimistic ? "Remove key shot" : "Mark as key shot"}
      disabled={isPending}
      onClick={handle}
      className={cn(
        "relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-amber-400 disabled:opacity-50",
        optimistic ? "bg-amber-500" : "bg-zinc-600 hover:bg-zinc-500"
      )}
    >
      <span
        className={cn(
          "pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow-lg transition-transform",
          optimistic ? "translate-x-4" : "translate-x-0"
        )}
      />
    </button>
  );
}

function ShotTable({
  shots,
  canManage,
  projectId,
  selectedIds,
  onToggle,
  onToggleAll,
}: {
  shots: ShotRow[];
  canManage: boolean;
  projectId: string;
  selectedIds: Set<string>;
  onToggle: (id: string) => void;
  onToggleAll: (ids: string[], checked: boolean) => void;
}) {
  const allChecked = shots.length > 0 && shots.every((s) => selectedIds.has(s.id));
  const someChecked = shots.some((s) => selectedIds.has(s.id));

  return (
    <table className="w-full text-sm">
      <thead>
        <tr className="border-b border-zinc-800">
          {canManage && (
            <th className="py-2 px-3 w-9">
              <IndeterminateCheckbox
                checked={allChecked}
                indeterminate={someChecked && !allChecked}
                onChange={(e) => onToggleAll(shots.map((s) => s.id), e.target.checked)}
              />
            </th>
          )}
          <th className="text-left py-2 px-3 text-xs font-medium text-zinc-500 w-32">Thumb</th>
          <th className="text-left py-2 px-3 text-xs font-medium text-zinc-500">Shot</th>
          <th className="text-left py-2 px-3 text-xs font-medium text-zinc-500 w-32">Status</th>
          <th className="text-left py-2 px-3 text-xs font-medium text-zinc-500 w-32">Due Date</th>
          <th className="text-left py-2 px-3 text-xs font-medium text-zinc-500">Notes</th>
          <th className="py-2 px-3 text-xs font-medium text-zinc-500 w-20 text-center">
            <span className="flex items-center gap-1 justify-center">
              <Star className="h-3 w-3" />
              Key
            </span>
          </th>
        </tr>
      </thead>
      <tbody className="divide-y divide-zinc-800/60">
        {shots.map((shot) => {
          const cfg = STATUS_CONFIG[shot.status] ?? STATUS_CONFIG.WAITING;
          const StatusIcon = cfg.icon;
          const dueDate = shot.dueDate ? new Date(shot.dueDate) : null;
          const isOverdue = dueDate && dueDate < new Date() && shot.status !== "COMPLETE";
          const isSelected = selectedIds.has(shot.id);

          return (
            <tr key={shot.id} className={cn(
              "transition-colors",
              shot.isKeyShot
                ? "bg-amber-500/5 hover:bg-amber-500/10 border-l-2 border-l-amber-500"
                : "hover:bg-zinc-800/30",
              isSelected && "bg-blue-500/5 hover:bg-blue-500/10"
            )}>
              {/* Checkbox */}
              {canManage && (
                <td className="py-2 px-3">
                  <input
                    type="checkbox"
                    checked={isSelected}
                    onChange={() => onToggle(shot.id)}
                    className="cursor-pointer accent-blue-500 w-3.5 h-3.5"
                  />
                </td>
              )}

              {/* Thumbnail */}
              <td className="py-2 px-3">
                <div className="w-24 aspect-[2.39/1] rounded overflow-hidden bg-zinc-800 flex items-center justify-center shrink-0">
                  {shot.thumbnailUrl ? (
                    <Image
                      src={shot.thumbnailUrl}
                      alt={shot.shotCode}
                      width={96}
                      height={40}
                      className="object-cover w-full h-full"
                    />
                  ) : (
                    <Film className="h-4 w-4 text-zinc-600" />
                  )}
                </div>
              </td>

              {/* Shot name */}
              <td className="py-2 px-3">
                <div className="flex items-center gap-1.5">
                  {shot.isKeyShot && (
                    <Star className="h-3 w-3 text-amber-400 fill-amber-400 shrink-0" />
                  )}
                  <Link
                    href={`/projects/${projectId}/shots/${shot.id}`}
                    className="font-mono text-sm text-white hover:text-blue-400 transition-colors"
                    onClick={() => sessionStorage.setItem(SCROLL_KEY, String(window.scrollY))}
                  >
                    {shot.shotCode}
                  </Link>
                </div>
                {shot.description && (
                  <p className="text-xs text-zinc-500 mt-0.5 truncate max-w-[200px]">
                    {shot.description}
                  </p>
                )}
              </td>

              {/* Status */}
              <td className="py-2 px-3">
                <Badge className={cn("gap-1 text-xs", cfg.color)}>
                  <StatusIcon className="h-3 w-3" />
                  {cfg.label}
                </Badge>
              </td>

              {/* Due date */}
              <td className="py-2 px-3">
                {dueDate ? (
                  <span
                    className={cn(
                      "flex items-center gap-1 text-xs",
                      isOverdue ? "text-red-400" : "text-zinc-400"
                    )}
                  >
                    <Calendar className="h-3 w-3" />
                    {format(dueDate, "d MMM yyyy")}
                  </span>
                ) : (
                  <span className="text-xs text-zinc-600 italic">—</span>
                )}
              </td>

              {/* Notes */}
              <td className="py-2 px-3 min-w-[220px]">
                <NotesCell shot={shot} canManage={canManage} />
              </td>

              {/* Key shot toggle */}
              <td className="py-2 px-3 text-center">
                <KeyShotToggle shot={shot} />
              </td>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

export function ShotStatusClient({
  projects,
  selectedProjectId,
  selectedProject,
  shots,
  episodeDueDates,
  canManage,
}: ShotStatusClientProps) {
  const router = useRouter();
  const { toast } = useToast();

  // Restore scroll position when shots load
  useEffect(() => {
    const saved = sessionStorage.getItem(SCROLL_KEY);
    if (saved) {
      sessionStorage.removeItem(SCROLL_KEY);
      requestAnimationFrame(() => window.scrollTo(0, parseInt(saved, 10)));
    }
  }, [shots]);

  // Restore last selected project if no project is currently selected
  useEffect(() => {
    if (!selectedProjectId) {
      const saved = localStorage.getItem("shotStatus:lastProjectId");
      if (saved && projects.some((p) => p.id === saved)) {
        router.replace(`/shot-status?projectId=${saved}`);
      }
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const [expandedEpisodes, setExpandedEpisodes] = useState<Set<string>>(new Set());
  const [expandedScenes, setExpandedScenes] = useState<Set<string>>(new Set());
  const [groupByScene, setGroupByScene] = useState(false);
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());

  // Load saved episode expand state when project changes
  useEffect(() => {
    if (!selectedProjectId) return;
    try {
      const saved = localStorage.getItem(`shotStatus:${selectedProjectId}:episodeExpand`);
      setExpandedEpisodes(saved ? new Set(JSON.parse(saved) as string[]) : new Set());
    } catch {
      setExpandedEpisodes(new Set());
    }
    try {
      const savedGroup = localStorage.getItem(`shotStatus:${selectedProjectId}:groupByScene`);
      setGroupByScene(savedGroup === "1");
    } catch {
      setGroupByScene(false);
    }
  }, [selectedProjectId]);
  const [dueDateDialogOpen, setDueDateDialogOpen] = useState(false);

  const toggleEpisode = (ep: string) =>
    setExpandedEpisodes((prev) => {
      const next = new Set(prev);
      next.has(ep) ? next.delete(ep) : next.add(ep);
      if (selectedProjectId) {
        try {
          localStorage.setItem(`shotStatus:${selectedProjectId}:episodeExpand`, JSON.stringify([...next]));
        } catch {}
      }
      return next;
    });

  const toggleScene = (sc: string) =>
    setExpandedScenes((prev) => {
      const next = new Set(prev);
      next.has(sc) ? next.delete(sc) : next.add(sc);
      return next;
    });

  const handleGroupByScene = (checked: boolean) => {
    setGroupByScene(checked);
    if (checked) setExpandedScenes(new Set(shots.map((s) => s.scene)));
    if (selectedProjectId) {
      try { localStorage.setItem(`shotStatus:${selectedProjectId}:groupByScene`, checked ? "1" : "0"); } catch {}
    }
  };

  const handleProjectChange = (id: string) => {
    localStorage.setItem("shotStatus:lastProjectId", id);
    setSelectedIds(new Set());
    router.push(`/shot-status?projectId=${id}`);
  };

  const toggleShot = (id: string) =>
    setSelectedIds((prev) => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });

  const toggleMany = (ids: string[], checked: boolean) =>
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (checked) ids.forEach((id) => next.add(id));
      else ids.forEach((id) => next.delete(id));
      return next;
    });

  const clearSelection = () => setSelectedIds(new Set());

  const handleBulkDueDate = async (date: string, includeTasks: boolean) => {
    try {
      const result = await bulkUpdateDueDates([...selectedIds], date, includeTasks);
      toast({
        title: `Due date updated for ${result.updated} shot${result.updated !== 1 ? "s" : ""}`,
      });
      setDueDateDialogOpen(false);
      clearSelection();
      router.refresh();
    } catch {
      toast({ title: "Failed to update due dates", variant: "destructive" });
    }
  };

  // Group by episode for episodic projects
  const isEpisodic = selectedProject?.projectType === "EPISODIC";
  const episodeGroups: [string, ShotRow[]][] = isEpisodic
    ? (() => {
        const map = new Map<string, ShotRow[]>();
        for (const shot of shots) {
          const key = shot.episode ?? "(No Episode)";
          if (!map.has(key)) map.set(key, []);
          map.get(key)!.push(shot);
        }
        return Array.from(map.entries());
      })()
    : [];

  const sceneGroups: [string, ShotRow[]][] = !isEpisodic && groupByScene
    ? (() => {
        const map = new Map<string, ShotRow[]>();
        for (const shot of shots) {
          const key = shot.scene || "(No Scene)";
          if (!map.has(key)) map.set(key, []);
          map.get(key)!.push(shot);
        }
        return Array.from(map.entries());
      })()
    : [];

  const episodeDueDateMap = new Map(
    episodeDueDates.map((e) => [e.episode, new Date(e.dueDate)])
  );

  const statusCounts = shots.reduce(
    (acc, s) => {
      acc[s.status] = (acc[s.status] ?? 0) + 1;
      return acc;
    },
    {} as Record<string, number>
  );

  const selectionCount = selectedIds.size;

  return (
    <div className="p-8 space-y-6 max-w-[1600px] mx-auto">
      {/* Header */}
      <div>
        <h1 className="text-3xl font-bold text-white">Shot Status</h1>
        <p className="text-zinc-400 mt-1">Track shot progress and add production notes</p>
      </div>

      {/* Project selector */}
      <div className="flex items-center gap-3">
        <label className="text-sm text-zinc-400 shrink-0">Project:</label>
        <Select value={selectedProjectId ?? ""} onValueChange={handleProjectChange}>
          <SelectTrigger className="w-72">
            <SelectValue placeholder="Select a project..." />
          </SelectTrigger>
          <SelectContent>
            {projects.map((p) => (
              <SelectItem key={p.id} value={p.id}>
                <span className="font-mono text-xs text-zinc-400 mr-2">{p.code}</span>
                {p.name}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
        {selectedProject && !isEpisodic && (
          <label className="flex items-center gap-2 cursor-pointer select-none">
            <input
              type="checkbox"
              checked={groupByScene}
              onChange={(e) => handleGroupByScene(e.target.checked)}
              className="cursor-pointer accent-blue-500 w-3.5 h-3.5"
            />
            <span className="text-sm text-zinc-400">Group by scene</span>
          </label>
        )}
      </div>

      {/* No project selected */}
      {!selectedProject && (
        <div className="text-center py-20 text-zinc-500">
          <Film className="h-10 w-10 mx-auto mb-3 opacity-30" />
          <p>Select a project to view shot status</p>
        </div>
      )}

      {/* Shots table */}
      {selectedProject && shots.length === 0 && (
        <div className="text-center py-20 text-zinc-500">
          <Film className="h-10 w-10 mx-auto mb-3 opacity-30" />
          <p>No shots in this project yet</p>
        </div>
      )}

      {selectedProject && shots.length > 0 && (
        <>
          {/* Summary / selection bar */}
          <div className="flex flex-wrap items-center gap-2">
            {selectionCount === 0 ? (
              <>
                <span className="text-xs text-zinc-500 self-center">{shots.length} shots total</span>
                {Object.entries(STATUS_CONFIG).map(([key, cfg]) => {
                  const count = statusCounts[key] ?? 0;
                  if (!count) return null;
                  return (
                    <Badge key={key} className={cn("gap-1 text-xs", cfg.color)}>
                      {count} {cfg.label}
                    </Badge>
                  );
                })}
              </>
            ) : (
              <div className="flex items-center gap-3 rounded-lg border border-blue-500/30 bg-blue-500/10 px-4 py-2">
                <span className="text-sm font-medium text-blue-300">
                  {selectionCount} shot{selectionCount !== 1 ? "s" : ""} selected
                </span>
                <Button
                  size="sm"
                  variant="outline"
                  className="h-7 gap-1.5 border-blue-500/40 text-blue-300 hover:bg-blue-500/20 hover:text-blue-200"
                  onClick={() => setDueDateDialogOpen(true)}
                >
                  <CalendarDays className="h-3.5 w-3.5" />
                  Change Due Date
                </Button>
                <button
                  onClick={clearSelection}
                  className="text-zinc-500 hover:text-zinc-300 transition-colors"
                  aria-label="Clear selection"
                >
                  <X className="h-4 w-4" />
                </button>
              </div>
            )}
          </div>

          {/* Table */}
          <div className="rounded-xl border border-zinc-800 bg-zinc-900/50 overflow-hidden">
            {isEpisodic ? (
              <div className="divide-y divide-zinc-800">
                {episodeGroups.map(([episode, episodeShots]) => {
                  const collapsed = !expandedEpisodes.has(episode);
                  const episodeIds = episodeShots.map((s) => s.id);
                  const allEpSelected = episodeIds.every((id) => selectedIds.has(id));
                  const someEpSelected = episodeIds.some((id) => selectedIds.has(id));
                  const epDueDate = episodeDueDateMap.get(episode);
                  const epIsOverdue = epDueDate && epDueDate < new Date();
                  return (
                    <div key={episode}>
                      <div className="flex items-center gap-2 px-4 py-3 bg-zinc-800/60 hover:bg-zinc-800/90 transition-colors">
                        {canManage && (
                          <IndeterminateCheckbox
                            checked={allEpSelected}
                            indeterminate={someEpSelected && !allEpSelected}
                            onChange={(e) => toggleMany(episodeIds, e.target.checked)}
                            className="shrink-0"
                          />
                        )}
                        <button
                          onClick={() => toggleEpisode(episode)}
                          className="flex items-center gap-2 flex-1 text-left"
                        >
                          {collapsed ? (
                            <ChevronRight className="h-4 w-4 text-zinc-400 shrink-0" />
                          ) : (
                            <ChevronDown className="h-4 w-4 text-zinc-400 shrink-0" />
                          )}
                          <span className="font-semibold text-sm text-white">Episode {episode}</span>
                          <span className="text-xs text-zinc-500 font-normal">
                            {episodeShots.length} shot{episodeShots.length !== 1 ? "s" : ""}
                          </span>
                          {epDueDate && (
                            <span className={cn(
                              "flex items-center gap-1 text-xs",
                              epIsOverdue ? "text-red-400" : "text-zinc-400"
                            )}>
                              <Calendar className="h-3 w-3" />
                              {format(epDueDate, "d MMM yyyy")}
                            </span>
                          )}
                        </button>
                      </div>
                      {!collapsed && (
                        <div className="overflow-x-auto">
                          <ShotTable
                            shots={episodeShots}
                            canManage={canManage}
                            projectId={selectedProjectId!}
                            selectedIds={selectedIds}
                            onToggle={toggleShot}
                            onToggleAll={toggleMany}
                          />
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            ) : groupByScene ? (
              <div className="divide-y divide-zinc-800">
                {sceneGroups.map(([scene, sceneShots]) => {
                  const collapsed = !expandedScenes.has(scene);
                  const sceneIds = sceneShots.map((s) => s.id);
                  const allScSelected = sceneIds.every((id) => selectedIds.has(id));
                  const someScSelected = sceneIds.some((id) => selectedIds.has(id));
                  return (
                    <div key={scene}>
                      <div className="flex items-center gap-2 px-4 py-3 bg-zinc-800/60 hover:bg-zinc-800/90 transition-colors">
                        {canManage && (
                          <IndeterminateCheckbox
                            checked={allScSelected}
                            indeterminate={someScSelected && !allScSelected}
                            onChange={(e) => toggleMany(sceneIds, e.target.checked)}
                            className="shrink-0"
                          />
                        )}
                        <button
                          onClick={() => toggleScene(scene)}
                          className="flex items-center gap-2 flex-1 text-left"
                        >
                          {collapsed ? (
                            <ChevronRight className="h-4 w-4 text-zinc-400 shrink-0" />
                          ) : (
                            <ChevronDown className="h-4 w-4 text-zinc-400 shrink-0" />
                          )}
                          <span className="font-semibold text-sm text-white">Scene {scene}</span>
                          <span className="text-xs text-zinc-500 font-normal">
                            {sceneShots.length} shot{sceneShots.length !== 1 ? "s" : ""}
                          </span>
                        </button>
                      </div>
                      {!collapsed && (
                        <div className="overflow-x-auto">
                          <ShotTable
                            shots={sceneShots}
                            canManage={canManage}
                            projectId={selectedProjectId!}
                            selectedIds={selectedIds}
                            onToggle={toggleShot}
                            onToggleAll={toggleMany}
                          />
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            ) : (
              <div className="overflow-x-auto">
                <ShotTable
                  shots={shots}
                  canManage={canManage}
                  projectId={selectedProjectId!}
                  selectedIds={selectedIds}
                  onToggle={toggleShot}
                  onToggleAll={toggleMany}
                />
              </div>
            )}
          </div>
        </>
      )}

      {/* Bulk due date dialog */}
      <BulkDueDateDialog
        open={dueDateDialogOpen}
        onClose={() => setDueDateDialogOpen(false)}
        onApply={handleBulkDueDate}
        count={selectionCount}
      />
    </div>
  );
}
