"use client";

import { useState, useEffect, useMemo } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Music,
  Download,
  Square,
  Play,
  Pause,
  Loader2,
  ExternalLink,
  CheckCircle2,
  XCircle,
  Clock,
  RefreshCw,
  Trash2,
  Search,
  ChevronDown,
  ChevronRight,
  Library,
  Briefcase,
  Sparkles,
} from "lucide-react";
import { toast } from "sonner";
import {
  useYouTubeDownload,
  type JobWithItems,
  type ItemWithPlaylist,
} from "@/lib/use-youtube-download";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Select } from "@/components/ui/select";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import type { Database, MusicGenre } from "@/lib/supabase";
import { MUSIC_GENRES, GENRE_LABELS } from "@/lib/supabase";

type DownloadJob = Database["public"]["Tables"]["download_jobs"]["Row"];
type DownloadItem = Database["public"]["Tables"]["download_items"]["Row"];

type MusicView = "library" | "jobs";

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function formatDuration(seconds: number | null): string {
  if (!seconds) return "--:--";
  const m = Math.floor(seconds / 60);
  const s = seconds % 60;
  return `${m}:${s.toString().padStart(2, "0")}`;
}

function statusBadge(status: string) {
  switch (status) {
    case "completed":
      return (
        <Badge className="bg-emerald-500/20 text-emerald-400 border-emerald-500/30">
          <CheckCircle2 className="w-3 h-3 mr-1" />
          Completed
        </Badge>
      );
    case "downloading":
    case "processing":
      return (
        <Badge className="bg-yellow-500/20 text-yellow-400 border-yellow-500/30">
          <Loader2 className="w-3 h-3 mr-1 animate-spin" />
          {status === "downloading" ? "Downloading" : "Processing"}
        </Badge>
      );
    case "failed":
      return (
        <Badge className="bg-red-500/20 text-red-400 border-red-500/30">
          <XCircle className="w-3 h-3 mr-1" />
          Failed
        </Badge>
      );
    default:
      return (
        <Badge className="bg-neutral-500/20 text-neutral-400 border-neutral-500/30">
          <Clock className="w-3 h-3 mr-1" />
          Pending
        </Badge>
      );
  }
}

function progressPercent(job: DownloadJob): number {
  if (job.total_items === 0) return 0;
  return Math.round(
    ((job.completed_items + job.failed_items) / job.total_items) * 100
  );
}

const genreOptions = MUSIC_GENRES.map((g) => ({
  value: g,
  label: GENRE_LABELS[g],
}));

const genreSelectOptions = [
  { value: "", label: "No genre" },
  ...genreOptions,
];

const genreFilterOptions = [
  { value: "", label: "All genres" },
  ...genreOptions,
];

const statusFilterOptions = [
  { value: "", label: "All statuses" },
  { value: "completed", label: "Completed" },
  { value: "pending", label: "Pending" },
  { value: "downloading", label: "Downloading" },
  { value: "failed", label: "Failed" },
];

// ---------------------------------------------------------------------------
// Sub-components
// ---------------------------------------------------------------------------

function ViewChips({
  active,
  onChange,
  allCount,
  jobCount,
}: {
  active: MusicView;
  onChange: (view: MusicView) => void;
  allCount: number;
  jobCount: number;
}) {
  return (
    <div className="flex gap-2">
      <button
        onClick={() => onChange("library")}
        className={`flex items-center gap-2 px-4 py-2 rounded-full text-sm font-medium transition-colors ${
          active === "library"
            ? "bg-orange-500 text-white"
            : "bg-neutral-800 text-neutral-400 hover:text-white hover:bg-neutral-700"
        }`}
      >
        <Library className="w-4 h-4" />
        All Music
        <span
          className={`text-xs px-1.5 py-0.5 rounded-full ${
            active === "library"
              ? "bg-white/20 text-white"
              : "bg-neutral-700 text-neutral-400"
          }`}
          style={{ fontVariant: "tabular-nums" }}
        >
          {allCount}
        </span>
      </button>
      <button
        onClick={() => onChange("jobs")}
        className={`flex items-center gap-2 px-4 py-2 rounded-full text-sm font-medium transition-colors ${
          active === "jobs"
            ? "bg-orange-500 text-white"
            : "bg-neutral-800 text-neutral-400 hover:text-white hover:bg-neutral-700"
        }`}
      >
        <Briefcase className="w-4 h-4" />
        Jobs
        <span
          className={`text-xs px-1.5 py-0.5 rounded-full ${
            active === "jobs"
              ? "bg-white/20 text-white"
              : "bg-neutral-700 text-neutral-400"
          }`}
          style={{ fontVariant: "tabular-nums" }}
        >
          {jobCount}
        </span>
      </button>
    </div>
  );
}

function ImportSection({
  onImport,
  isImporting,
}: {
  onImport: (url: string, genre?: MusicGenre) => void;
  isImporting: boolean;
}) {
  const [url, setUrl] = useState("");
  const [genre, setGenre] = useState<string>("");

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const trimmed = url.trim();
    if (!trimmed) return;
    onImport(trimmed, (genre || undefined) as MusicGenre | undefined);
    setUrl("");
  };

  return (
    <Card className="bg-neutral-900 border-neutral-800">
      <CardHeader>
        <CardTitle className="text-white flex items-center gap-2">
          <Music className="w-5 h-5 text-orange-500" />
          Import YouTube Playlist
        </CardTitle>
      </CardHeader>
      <CardContent>
        <form onSubmit={handleSubmit} className="flex gap-3">
          <Input
            value={url}
            onChange={(e) => setUrl(e.target.value)}
            placeholder="https://www.youtube.com/playlist?list=..."
            className="bg-neutral-950 border-neutral-700 text-white placeholder:text-neutral-500 flex-1"
            disabled={isImporting}
          />
          <Select
            value={genre}
            onValueChange={setGenre}
            options={genreSelectOptions}
            placeholder="Genre"
            disabled={isImporting}
            className="w-40"
          />
          <Button
            type="submit"
            disabled={isImporting || !url.trim()}
            className="bg-orange-500 hover:bg-orange-600 text-white"
          >
            {isImporting ? (
              <>
                <Loader2 className="w-4 h-4 mr-2 animate-spin" />
                Importing...
              </>
            ) : (
              <>
                <Download className="w-4 h-4 mr-2" />
                Import
              </>
            )}
          </Button>
        </form>
      </CardContent>
    </Card>
  );
}

function AudioPlayer({ url }: { url: string }) {
  const [playing, setPlaying] = useState(false);
  const [audio] = useState(() => {
    if (typeof window === "undefined") return null;
    const a = new Audio(url);
    a.addEventListener("ended", () => setPlaying(false));
    return a;
  });

  const toggle = () => {
    if (!audio) return;
    if (playing) {
      audio.pause();
      setPlaying(false);
    } else {
      audio.play();
      setPlaying(true);
    }
  };

  useEffect(() => {
    return () => {
      audio?.pause();
    };
  }, [audio]);

  return (
    <Button
      size="sm"
      variant="ghost"
      className="h-7 w-7 p-0 text-orange-500 hover:text-orange-400"
      onClick={toggle}
    >
      {playing ? (
        <Pause className="w-3.5 h-3.5" />
      ) : (
        <Play className="w-3.5 h-3.5" />
      )}
    </Button>
  );
}

// ---------------------------------------------------------------------------
// Filter bar for library view
// ---------------------------------------------------------------------------

function FilterBar({
  search,
  onSearchChange,
  genre,
  onGenreChange,
  status,
  onStatusChange,
}: {
  search: string;
  onSearchChange: (val: string) => void;
  genre: string;
  onGenreChange: (val: string) => void;
  status: string;
  onStatusChange: (val: string) => void;
}) {
  return (
    <div className="flex items-center gap-3 flex-wrap">
      <div className="relative flex-1 min-w-[200px] max-w-sm">
        <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-500" />
        <Input
          value={search}
          onChange={(e) => onSearchChange(e.target.value)}
          placeholder="Search by title..."
          className="bg-neutral-950 border-neutral-700 text-white placeholder:text-neutral-500 pl-9"
        />
      </div>
      <Select
        value={genre}
        onValueChange={onGenreChange}
        options={genreFilterOptions}
        placeholder="All genres"
        className="w-40"
      />
      <Select
        value={status}
        onValueChange={onStatusChange}
        options={statusFilterOptions}
        placeholder="All statuses"
        className="w-40"
      />
    </div>
  );
}

// ---------------------------------------------------------------------------
// All Music library table
// ---------------------------------------------------------------------------

function LibraryTable({
  items,
  onGenreChange,
  onDeleteItem,
}: {
  items: ItemWithPlaylist[];
  onGenreChange: (itemId: string, genre: MusicGenre | null) => void;
  onDeleteItem: (item: ItemWithPlaylist) => void;
}) {
  if (items.length === 0) {
    return (
      <div className="py-16 text-center">
        <Music className="w-12 h-12 text-neutral-700 mx-auto mb-4" />
        <p className="text-neutral-500">
          No tracks match your filters.
        </p>
      </div>
    );
  }

  return (
    <Table>
      <TableHeader>
        <TableRow className="border-neutral-800 hover:bg-transparent">
          <TableHead className="text-neutral-400 w-12">#</TableHead>
          <TableHead className="text-neutral-400">Title</TableHead>
          <TableHead className="text-neutral-400">Playlist</TableHead>
          <TableHead className="text-neutral-400">Genre</TableHead>
          <TableHead className="text-neutral-400">Duration</TableHead>
          <TableHead className="text-neutral-400">Status</TableHead>
          <TableHead className="text-neutral-400 text-right">
            Actions
          </TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {items.map((item, idx) => (
          <TableRow key={item.id} className="border-neutral-800">
            <TableCell
              className="text-neutral-500"
              style={{ fontVariant: "tabular-nums" }}
            >
              {idx + 1}
            </TableCell>
            <TableCell>
              <div className="flex items-center gap-3">
                {item.thumbnail_url && (
                  <img
                    src={item.thumbnail_url}
                    alt=""
                    className="w-10 h-10 rounded object-cover bg-neutral-800 shrink-0"
                  />
                )}
                <span className="text-white truncate max-w-xs">
                  {item.title || item.video_id}
                </span>
              </div>
            </TableCell>
            <TableCell>
              <span className="text-neutral-400 text-sm truncate max-w-[160px] inline-block">
                {item.playlist_title || "—"}
              </span>
            </TableCell>
            <TableCell>
              <Select
                value={item.genre ?? ""}
                onValueChange={(val) =>
                  onGenreChange(
                    item.id,
                    (val || null) as MusicGenre | null
                  )
                }
                options={genreSelectOptions}
                placeholder="--"
                className="w-32"
              />
            </TableCell>
            <TableCell
              className="text-neutral-400"
              style={{ fontVariant: "tabular-nums" }}
            >
              {formatDuration(item.duration_seconds)}
            </TableCell>
            <TableCell>{statusBadge(item.status)}</TableCell>
            <TableCell className="text-right">
              <div className="flex items-center justify-end gap-1">
                {item.status === "completed" && item.public_url && (
                  <AudioPlayer url={item.public_url} />
                )}
                <a
                  href={`https://www.youtube.com/watch?v=${item.video_id}`}
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  <Button
                    size="sm"
                    variant="ghost"
                    className="h-7 w-7 p-0 text-neutral-400 hover:text-white"
                  >
                    <ExternalLink className="w-3.5 h-3.5" />
                  </Button>
                </a>
                <Button
                  size="sm"
                  variant="ghost"
                  className="h-7 w-7 p-0 text-neutral-500 hover:text-red-400 hover:bg-red-500/10"
                  onClick={() => onDeleteItem(item)}
                >
                  <Trash2 className="w-3.5 h-3.5" />
                </Button>
              </div>
              {item.status === "failed" && item.error_message && (
                <p className="text-red-400 text-xs mt-1 text-right max-w-xs truncate">
                  {item.error_message}
                </p>
              )}
            </TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  );
}

// ---------------------------------------------------------------------------
// Jobs view: expandable job cards
// ---------------------------------------------------------------------------

function ExpandableJobCard({
  job,
  isProcessing,
  isClassifying,
  isExpanded,
  onToggle,
  onStart,
  onStop,
  onDelete,
  onReclassify,
  onForceReclassify,
  onGenreChange,
  onDeleteItem,
  items,
}: {
  job: DownloadJob;
  isProcessing: boolean;
  isClassifying: boolean;
  isExpanded: boolean;
  onToggle: () => void;
  onStart: () => void;
  onStop: () => void;
  onDelete: () => void;
  onReclassify: () => void;
  onForceReclassify: () => void;
  onGenreChange: (itemId: string, genre: MusicGenre | null) => void;
  onDeleteItem: (item: DownloadItem) => void;
  items: DownloadItem[];
}) {
  const pct = progressPercent(job);
  const canStart =
    !isProcessing &&
    (job.status === "pending" || job.status === "processing");

  return (
    <Card className="bg-neutral-900 border-neutral-800">
      <CardContent className="pt-6 pb-4">
        {/* Header row — always visible */}
        <div
          className="flex items-start justify-between gap-4 cursor-pointer"
          onClick={onToggle}
        >
          <div className="flex items-start gap-3 flex-1 min-w-0">
            <div className="pt-0.5">
              {isExpanded ? (
                <ChevronDown className="w-4 h-4 text-neutral-500" />
              ) : (
                <ChevronRight className="w-4 h-4 text-neutral-500" />
              )}
            </div>
            <div className="flex-1 min-w-0">
              <p className="text-white font-medium truncate">
                {job.playlist_title || "Untitled Playlist"}
              </p>
              <p className="text-neutral-500 text-sm mt-1 truncate">
                {job.playlist_url}
              </p>
              <div className="flex items-center gap-3 mt-2">
                {statusBadge(job.status)}
                <span
                  className="text-neutral-400 text-sm"
                  style={{ fontVariant: "tabular-nums" }}
                >
                  {job.completed_items}/{job.total_items} completed
                  {job.failed_items > 0 &&
                    ` · ${job.failed_items} failed`}
                </span>
              </div>
            </div>
          </div>
          <div
            className="flex gap-2 shrink-0"
            onClick={(e) => e.stopPropagation()}
          >
            {isProcessing ? (
              <Button
                size="sm"
                variant="outline"
                className="border-neutral-700 text-neutral-300 hover:bg-neutral-800"
                onClick={onStop}
              >
                <Square className="w-4 h-4 mr-1" />
                Stop
              </Button>
            ) : (
              canStart && (
                <Button
                  size="sm"
                  className="bg-orange-500 hover:bg-orange-600 text-white"
                  onClick={onStart}
                >
                  <Download className="w-4 h-4 mr-1" />
                  Start
                </Button>
              )
            )}
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <Button
                  size="sm"
                  variant="outline"
                  className="border-neutral-700 text-neutral-300 hover:bg-neutral-800"
                  disabled={isClassifying || isProcessing}
                >
                  {isClassifying ? (
                    <Loader2 className="w-4 h-4 mr-1 animate-spin" />
                  ) : (
                    <Sparkles className="w-4 h-4 mr-1" />
                  )}
                  Classify
                  <ChevronDown className="w-3 h-3 ml-1" />
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent
                align="end"
                className="bg-neutral-900 border-neutral-800"
              >
                <DropdownMenuItem
                  className="text-neutral-200 focus:bg-neutral-800 focus:text-white cursor-pointer"
                  onClick={onReclassify}
                >
                  <Sparkles className="w-4 h-4 mr-2" />
                  Classify missing
                </DropdownMenuItem>
                <DropdownMenuItem
                  className="text-orange-400 focus:bg-orange-500/10 focus:text-orange-300 cursor-pointer"
                  onClick={onForceReclassify}
                >
                  <RefreshCw className="w-4 h-4 mr-2" />
                  Re-classify all...
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
            <Button
              size="sm"
              variant="ghost"
              className="h-8 w-8 p-0 text-neutral-500 hover:text-red-400 hover:bg-red-500/10"
              onClick={onDelete}
            >
              <Trash2 className="w-4 h-4" />
            </Button>
          </div>
        </div>

        {/* Progress bar */}
        <div className="mt-3 h-1.5 bg-neutral-800 rounded-full overflow-hidden">
          <div
            className="h-full bg-orange-500 rounded-full transition-all duration-300"
            style={{ width: `${pct}%` }}
          />
        </div>

        {/* Expandable items table */}
        {isExpanded && (
          <div className="mt-4 border-t border-neutral-800 pt-4">
            {items.length === 0 ? (
              <p className="text-neutral-500 text-sm text-center py-4">
                No items in this job.
              </p>
            ) : (
              <Table>
                <TableHeader>
                  <TableRow className="border-neutral-800 hover:bg-transparent">
                    <TableHead className="text-neutral-400">#</TableHead>
                    <TableHead className="text-neutral-400">
                      Title
                    </TableHead>
                    <TableHead className="text-neutral-400">
                      Genre
                    </TableHead>
                    <TableHead className="text-neutral-400">
                      Duration
                    </TableHead>
                    <TableHead className="text-neutral-400">
                      Status
                    </TableHead>
                    <TableHead className="text-neutral-400 text-right">
                      Actions
                    </TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {items.map((item, idx) => (
                    <TableRow
                      key={item.id}
                      className="border-neutral-800"
                    >
                      <TableCell
                        className="text-neutral-500"
                        style={{ fontVariant: "tabular-nums" }}
                      >
                        {idx + 1}
                      </TableCell>
                      <TableCell>
                        <div className="flex items-center gap-3">
                          {item.thumbnail_url && (
                            <img
                              src={item.thumbnail_url}
                              alt=""
                              className="w-10 h-10 rounded object-cover bg-neutral-800 shrink-0"
                            />
                          )}
                          <span className="text-white truncate max-w-xs">
                            {item.title || item.video_id}
                          </span>
                        </div>
                      </TableCell>
                      <TableCell>
                        <Select
                          value={item.genre ?? ""}
                          onValueChange={(val) =>
                            onGenreChange(
                              item.id,
                              (val || null) as MusicGenre | null
                            )
                          }
                          options={genreSelectOptions}
                          placeholder="--"
                          className="w-32"
                        />
                      </TableCell>
                      <TableCell
                        className="text-neutral-400"
                        style={{ fontVariant: "tabular-nums" }}
                      >
                        {formatDuration(item.duration_seconds)}
                      </TableCell>
                      <TableCell>
                        {statusBadge(item.status)}
                      </TableCell>
                      <TableCell className="text-right">
                        <div className="flex items-center justify-end gap-1">
                          {item.status === "completed" &&
                            item.public_url && (
                              <AudioPlayer url={item.public_url} />
                            )}
                          <a
                            href={`https://www.youtube.com/watch?v=${item.video_id}`}
                            target="_blank"
                            rel="noopener noreferrer"
                          >
                            <Button
                              size="sm"
                              variant="ghost"
                              className="h-7 w-7 p-0 text-neutral-400 hover:text-white"
                            >
                              <ExternalLink className="w-3.5 h-3.5" />
                            </Button>
                          </a>
                          <Button
                            size="sm"
                            variant="ghost"
                            className="h-7 w-7 p-0 text-neutral-500 hover:text-red-400 hover:bg-red-500/10"
                            onClick={() => onDeleteItem(item)}
                          >
                            <Trash2 className="w-3.5 h-3.5" />
                          </Button>
                        </div>
                        {item.status === "failed" &&
                          item.error_message && (
                            <p className="text-red-400 text-xs mt-1 text-right max-w-xs truncate">
                              {item.error_message}
                            </p>
                          )}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            )}
          </div>
        )}
      </CardContent>
    </Card>
  );
}

// ---------------------------------------------------------------------------
// Main page
// ---------------------------------------------------------------------------

export default function MusicPage() {
  const {
    jobs,
    allItems,
    activeJob,
    isProcessing,
    isImporting,
    isClassifying,
    fetchJobs,
    fetchAllItems,
    refreshStatus,
    importPlaylist,
    startProcessing,
    stopProcessing,
    deleteJob,
    deleteItem,
    updateItemGenre,
    reclassifyJob,
  } = useYouTubeDownload();

  const [view, setView] = useState<MusicView>("library");
  const [expandedJobId, setExpandedJobId] = useState<string | null>(null);
  const [processingJobId, setProcessingJobId] = useState<string | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<DownloadJob | null>(null);
  const [deleteItemTarget, setDeleteItemTarget] = useState<DownloadItem | null>(null);
  const [isDeleting, setIsDeleting] = useState(false);
  const [reclassifyTarget, setReclassifyTarget] = useState<DownloadJob | null>(null);

  // Filter state
  const [searchQuery, setSearchQuery] = useState("");
  const [filterGenre, setFilterGenre] = useState("");
  const [filterStatus, setFilterStatus] = useState("");

  // Load data on mount
  useEffect(() => {
    fetchJobs().catch((err) =>
      toast.error("Failed to load jobs: " + err.message)
    );
    fetchAllItems().catch((err) =>
      toast.error("Failed to load music library: " + err.message)
    );
  }, [fetchJobs, fetchAllItems]);

  // Filtered library items
  const filteredItems = useMemo(() => {
    let result = allItems;
    if (searchQuery.trim()) {
      const q = searchQuery.toLowerCase();
      result = result.filter(
        (item) =>
          item.title?.toLowerCase().includes(q) ||
          item.video_id.toLowerCase().includes(q)
      );
    }
    if (filterGenre) {
      result = result.filter((item) => item.genre === filterGenre);
    }
    if (filterStatus) {
      result = result.filter((item) => item.status === filterStatus);
    }
    return result;
  }, [allItems, searchQuery, filterGenre, filterStatus]);

  const handleImport = async (url: string, genre?: MusicGenre) => {
    try {
      const result = await importPlaylist(url, genre);
      toast.success(
        `Imported "${result.playlistTitle}" — ${result.totalItems} tracks`
      );
      // Refresh library after import
      fetchAllItems().catch(() => {});
      setView("jobs");
    } catch (err) {
      toast.error(
        "Import failed: " +
          (err instanceof Error ? err.message : "Unknown error")
      );
    }
  };

  const handleStart = async (jobId: string) => {
    setProcessingJobId(jobId);
    setExpandedJobId(jobId);
    try {
      await startProcessing(jobId);
      toast.success("Download complete!");
      // Refresh the library view after processing
      fetchAllItems().catch(() => {});
    } catch (err) {
      toast.error(
        "Processing error: " +
          (err instanceof Error ? err.message : "Unknown error")
      );
    } finally {
      setProcessingJobId(null);
    }
  };

  const handleToggleJob = async (jobId: string) => {
    if (expandedJobId === jobId) {
      setExpandedJobId(null);
    } else {
      setExpandedJobId(jobId);
      try {
        await refreshStatus(jobId);
      } catch (err) {
        toast.error("Failed to load job details");
      }
    }
  };

  const handleDelete = async () => {
    if (!deleteTarget) return;
    setIsDeleting(true);
    try {
      await deleteJob(deleteTarget.id);
      toast.success(
        `Deleted "${deleteTarget.playlist_title || "Untitled Playlist"}"`
      );
      if (expandedJobId === deleteTarget.id) {
        setExpandedJobId(null);
      }
      // Refresh library after delete
      fetchAllItems().catch(() => {});
    } catch (err) {
      toast.error(
        "Delete failed: " +
          (err instanceof Error ? err.message : "Unknown error")
      );
    } finally {
      setIsDeleting(false);
      setDeleteTarget(null);
    }
  };

  const handleDeleteItem = async () => {
    if (!deleteItemTarget) return;
    setIsDeleting(true);
    try {
      await deleteItem(deleteItemTarget.id);
      toast.success(
        `Deleted "${deleteItemTarget.title || deleteItemTarget.video_id}"`
      );
      // Refresh job counters
      fetchJobs().catch(() => {});
    } catch (err) {
      toast.error(
        "Delete failed: " +
          (err instanceof Error ? err.message : "Unknown error")
      );
    } finally {
      setIsDeleting(false);
      setDeleteItemTarget(null);
    }
  };

  const handleGenreChange = async (
    itemId: string,
    genre: MusicGenre | null
  ) => {
    try {
      await updateItemGenre(itemId, genre);
      // Also update in allItems state
      fetchAllItems().catch(() => {});
    } catch (err) {
      toast.error(
        "Failed to update genre: " +
          (err instanceof Error ? err.message : "Unknown error")
      );
    }
  };

  const handleRefresh = async () => {
    try {
      await Promise.all([fetchJobs(), fetchAllItems()]);
    } catch (err) {
      toast.error("Failed to refresh");
    }
  };

  /** Classify only items with missing genres (force=false). */
  const handleReclassify = async (jobId: string) => {
    try {
      const result = await reclassifyJob(jobId, false);
      if (result.classified === 0) {
        toast.info("All tracks already have genres assigned");
      } else {
        toast.success(
          `Classified ${result.classified} track${result.classified === 1 ? "" : "s"}`
        );
      }
    } catch (err) {
      toast.error(
        "Classification failed: " +
          (err instanceof Error ? err.message : "Unknown error")
      );
    }
  };

  /** Force re-classify ALL items (overwrites manual edits). */
  const handleForceReclassify = async () => {
    if (!reclassifyTarget) return;
    try {
      const result = await reclassifyJob(reclassifyTarget.id, true);
      toast.success(
        `Re-classified ${result.classified} track${result.classified === 1 ? "" : "s"}`
      );
    } catch (err) {
      toast.error(
        "Classification failed: " +
          (err instanceof Error ? err.message : "Unknown error")
      );
    } finally {
      setReclassifyTarget(null);
    }
  };

  // Get items for a specific expanded job
  const getJobItems = (jobId: string): DownloadItem[] => {
    if (activeJob?.id === jobId) return activeJob.items;
    return [];
  };

  return (
    <div className="p-8 max-w-7xl">
      {/* Header */}
      <div className="mb-8 flex items-center justify-between">
        <div>
          <h1 className="text-3xl font-bold text-white mb-2">Music</h1>
          <p className="text-neutral-400">
            Download audio from YouTube playlists for workout tracks
          </p>
        </div>
        <Button
          variant="outline"
          size="sm"
          className="border-neutral-700 text-neutral-300 hover:bg-neutral-800"
          onClick={handleRefresh}
        >
          <RefreshCw className="w-4 h-4 mr-2" />
          Refresh
        </Button>
      </div>

      {/* Import section — always visible */}
      <div className="mb-6">
        <ImportSection onImport={handleImport} isImporting={isImporting} />
      </div>

      {/* View toggle chips */}
      <div className="mb-6">
        <ViewChips
          active={view}
          onChange={setView}
          allCount={allItems.length}
          jobCount={jobs.length}
        />
      </div>

      {/* --- ALL MUSIC library view --- */}
      {view === "library" && (
        <div className="space-y-4">
          <FilterBar
            search={searchQuery}
            onSearchChange={setSearchQuery}
            genre={filterGenre}
            onGenreChange={setFilterGenre}
            status={filterStatus}
            onStatusChange={setFilterStatus}
          />
          <Card className="bg-neutral-900 border-neutral-800">
            <CardContent className="p-0">
              <LibraryTable
                items={filteredItems}
                onGenreChange={handleGenreChange}
                onDeleteItem={setDeleteItemTarget}
              />
            </CardContent>
          </Card>
          {filteredItems.length > 0 && (
            <p
              className="text-neutral-500 text-sm text-right"
              style={{ fontVariant: "tabular-nums" }}
            >
              Showing {filteredItems.length} of {allItems.length} tracks
            </p>
          )}
        </div>
      )}

      {/* --- JOBS view --- */}
      {view === "jobs" && (
        <div className="space-y-3">
          {jobs.length === 0 ? (
            <Card className="bg-neutral-900 border-neutral-800">
              <CardContent className="py-16 text-center">
                <Briefcase className="w-12 h-12 text-neutral-700 mx-auto mb-4" />
                <p className="text-neutral-500">
                  No jobs yet. Import a playlist to get started.
                </p>
              </CardContent>
            </Card>
          ) : (
            jobs.map((job) => (
              <ExpandableJobCard
                key={job.id}
                job={job}
                isProcessing={
                  isProcessing && processingJobId === job.id
                }
                isClassifying={isClassifying}
                isExpanded={expandedJobId === job.id}
                onToggle={() => handleToggleJob(job.id)}
                onStart={() => handleStart(job.id)}
                onStop={stopProcessing}
                onDelete={() => setDeleteTarget(job)}
                onReclassify={() => handleReclassify(job.id)}
                onForceReclassify={() => setReclassifyTarget(job)}
                onGenreChange={handleGenreChange}
                onDeleteItem={setDeleteItemTarget}
                items={getJobItems(job.id)}
              />
            ))
          )}
        </div>
      )}

      {/* Delete confirmation dialog */}
      <Dialog
        open={!!deleteTarget}
        onOpenChange={(open) => {
          if (!open) setDeleteTarget(null);
        }}
      >
        <DialogContent className="bg-neutral-900 border-neutral-800">
          <DialogHeader>
            <DialogTitle className="text-white">Delete Job</DialogTitle>
            <DialogDescription className="text-neutral-400">
              This will permanently delete{" "}
              <span className="text-white font-medium">
                {deleteTarget?.playlist_title || "this job"}
              </span>{" "}
              and remove {deleteTarget?.completed_items ?? 0} audio files
              from storage. This action cannot be undone.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button
              variant="outline"
              className="border-neutral-700 text-neutral-300 hover:bg-neutral-800"
              onClick={() => setDeleteTarget(null)}
              disabled={isDeleting}
            >
              Cancel
            </Button>
            <Button
              className="bg-red-600 hover:bg-red-700 text-white"
              onClick={handleDelete}
              disabled={isDeleting}
            >
              {isDeleting ? (
                <>
                  <Loader2 className="w-4 h-4 mr-2 animate-spin" />
                  Deleting...
                </>
              ) : (
                <>
                  <Trash2 className="w-4 h-4 mr-2" />
                  Delete
                </>
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Delete single track confirmation dialog */}
      <Dialog
        open={!!deleteItemTarget}
        onOpenChange={(open) => {
          if (!open) setDeleteItemTarget(null);
        }}
      >
        <DialogContent className="bg-neutral-900 border-neutral-800">
          <DialogHeader>
            <DialogTitle className="text-white">Delete Track</DialogTitle>
            <DialogDescription className="text-neutral-400">
              This will permanently delete{" "}
              <span className="text-white font-medium">
                {deleteItemTarget?.title || deleteItemTarget?.video_id || "this track"}
              </span>{" "}
              and remove its audio file from storage. This action cannot be
              undone.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button
              variant="outline"
              className="border-neutral-700 text-neutral-300 hover:bg-neutral-800"
              onClick={() => setDeleteItemTarget(null)}
              disabled={isDeleting}
            >
              Cancel
            </Button>
            <Button
              className="bg-red-600 hover:bg-red-700 text-white"
              onClick={handleDeleteItem}
              disabled={isDeleting}
            >
              {isDeleting ? (
                <>
                  <Loader2 className="w-4 h-4 mr-2 animate-spin" />
                  Deleting...
                </>
              ) : (
                <>
                  <Trash2 className="w-4 h-4 mr-2" />
                  Delete
                </>
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Re-classify confirmation dialog (force mode) */}
      <Dialog
        open={!!reclassifyTarget}
        onOpenChange={(open) => {
          if (!open) setReclassifyTarget(null);
        }}
      >
        <DialogContent className="bg-neutral-900 border-neutral-800">
          <DialogHeader>
            <DialogTitle className="text-white">
              Re-classify All Genres?
            </DialogTitle>
            <DialogDescription className="text-neutral-400">
              This will overwrite all existing genres for{" "}
              <span className="text-white font-medium">
                {reclassifyTarget?.playlist_title || "this job"}
              </span>
              , including any you've manually set. Use the default
              &quot;Classify&quot; button to only fill in missing genres.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button
              variant="outline"
              className="border-neutral-700 text-neutral-300 hover:bg-neutral-800"
              onClick={() => setReclassifyTarget(null)}
              disabled={isClassifying}
            >
              Cancel
            </Button>
            <Button
              className="bg-orange-500 hover:bg-orange-600 text-white"
              onClick={handleForceReclassify}
              disabled={isClassifying}
            >
              {isClassifying ? (
                <>
                  <Loader2 className="w-4 h-4 mr-2 animate-spin" />
                  Classifying...
                </>
              ) : (
                <>
                  <Sparkles className="w-4 h-4 mr-2" />
                  Re-classify All
                </>
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
