"use client";

import { useState } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { Header } from "@/components/header";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  BriefcaseBusiness,
  Clock,
  PlayCircle,
  CheckCircle2,
  XCircle,
  ExternalLink,
  AlertCircle,
} from "lucide-react";
import { ListProjects, ListJobs, Job } from "@/lib/types";
import { format } from "date-fns";

export default function JobsPage() {
  const queryClient = useQueryClient();
  const [selectedProject, setSelectedProject] = useState<string>("");
  const [statusFilter, setStatusFilter] = useState<string>("all");
  const [cancelDialogOpen, setCancelDialogOpen] = useState(false);
  const [selectedJob, setSelectedJob] = useState<Job | null>(null);

  // Fetch projects
  const { data: projects, isLoading: isProjectsLoading } = useQuery({
    queryKey: ["projects"],
    queryFn: async (): Promise<ListProjects> => {
      const res = await fetch("/api/scrapyd/projects");
      if (!res.ok) throw new Error("Failed to fetch projects");
      return res.json();
    },
  });

  // Fetch jobs for selected project
  const { data: jobs, isLoading: isJobsLoading } = useQuery({
    queryKey: ["jobs", selectedProject],
    queryFn: async (): Promise<ListJobs> => {
      const res = await fetch(`/api/scrapyd/jobs?project=${selectedProject}`);
      if (!res.ok) throw new Error("Failed to fetch jobs");
      return res.json();
    },
    enabled: !!selectedProject,
    refetchInterval: 5000, // Refresh every 5 seconds for real-time updates
  });

  // Cancel job mutation
  const cancelJobMutation = useMutation({
    mutationFn: async (data: { project: string; job: string }) => {
      const res = await fetch("/api/scrapyd/jobs", {
        method: "DELETE",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(data),
      });
      if (!res.ok) throw new Error("Failed to cancel job");
      return res.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["jobs"] });
      queryClient.invalidateQueries({ queryKey: ["daemon-status"] });
      setCancelDialogOpen(false);
      setSelectedJob(null);
    },
  });

  const handleCancelJob = () => {
    if (selectedJob) {
      cancelJobMutation.mutate({
        project: selectedProject,
        job: selectedJob.id,
      });
    }
  };

  // Combine and filter jobs
  const allJobs: Array<Job & { status: string }> = [];
  if (jobs) {
    allJobs.push(...jobs.pending.map((j) => ({ ...j, status: "pending" })));
    allJobs.push(...jobs.running.map((j) => ({ ...j, status: "running" })));
    allJobs.push(...jobs.finished.map((j) => ({ ...j, status: "finished" })));
  }

  const filteredJobs =
    statusFilter === "all"
      ? allJobs
      : allJobs.filter((j) => j.status === statusFilter);

  const getStatusBadge = (status: string) => {
    switch (status) {
      case "pending":
        return (
          <Badge variant="outline" className="gap-1">
            <Clock className="h-3 w-3" />
            Pending
          </Badge>
        );
      case "running":
        return (
          <Badge className="gap-1 bg-green-500">
            <PlayCircle className="h-3 w-3" />
            Running
          </Badge>
        );
      case "finished":
        return (
          <Badge variant="secondary" className="gap-1">
            <CheckCircle2 className="h-3 w-3" />
            Finished
          </Badge>
        );
      default:
        return <Badge>{status}</Badge>;
    }
  };

  return (
    <div className="space-y-6">
      <Header
        title="Jobs"
        description="Monitor and manage scraping jobs"
      />

      {/* Filters */}
      <div className="grid gap-4 md:grid-cols-2">
        <Card>
          <CardHeader>
            <CardTitle>Project</CardTitle>
          </CardHeader>
          <CardContent>
            {isProjectsLoading ? (
              <Skeleton className="h-10 w-full" />
            ) : (
              <Select value={selectedProject} onValueChange={setSelectedProject}>
                <SelectTrigger>
                  <SelectValue placeholder="Select a project" />
                </SelectTrigger>
                <SelectContent>
                  {projects?.projects.map((project) => (
                    <SelectItem key={project} value={project}>
                      {project}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            )}
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Status Filter</CardTitle>
          </CardHeader>
          <CardContent>
            <Select value={statusFilter} onValueChange={setStatusFilter}>
              <SelectTrigger>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">All Jobs</SelectItem>
                <SelectItem value="pending">Pending</SelectItem>
                <SelectItem value="running">Running</SelectItem>
                <SelectItem value="finished">Finished</SelectItem>
              </SelectContent>
            </Select>
          </CardContent>
        </Card>
      </div>

      {/* Jobs Statistics */}
      {selectedProject && jobs && (
        <div className="grid gap-4 md:grid-cols-3">
          <Card>
            <CardHeader className="flex flex-row items-center justify-between pb-2">
              <CardTitle className="text-sm font-medium">Pending</CardTitle>
              <Clock className="h-4 w-4 text-yellow-500" />
            </CardHeader>
            <CardContent>
              <div className="text-2xl font-bold">{jobs.pending.length}</div>
            </CardContent>
          </Card>
          <Card>
            <CardHeader className="flex flex-row items-center justify-between pb-2">
              <CardTitle className="text-sm font-medium">Running</CardTitle>
              <PlayCircle className="h-4 w-4 text-green-500" />
            </CardHeader>
            <CardContent>
              <div className="text-2xl font-bold">{jobs.running.length}</div>
            </CardContent>
          </Card>
          <Card>
            <CardHeader className="flex flex-row items-center justify-between pb-2">
              <CardTitle className="text-sm font-medium">Finished</CardTitle>
              <CheckCircle2 className="h-4 w-4 text-blue-500" />
            </CardHeader>
            <CardContent>
              <div className="text-2xl font-bold">{jobs.finished.length}</div>
            </CardContent>
          </Card>
        </div>
      )}

      {/* Jobs Table */}
      {selectedProject && (
        <Card>
          <CardHeader>
            <CardTitle>
              Jobs for "{selectedProject}"
            </CardTitle>
          </CardHeader>
          <CardContent>
            {isJobsLoading ? (
              <div className="space-y-2">
                {[1, 2, 3].map((i) => (
                  <Skeleton key={i} className="h-16 w-full" />
                ))}
              </div>
            ) : filteredJobs.length > 0 ? (
              <div className="overflow-x-auto">
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead>Job ID</TableHead>
                      <TableHead>Spider</TableHead>
                      <TableHead>Status</TableHead>
                      <TableHead className="whitespace-nowrap">Start Time</TableHead>
                      <TableHead>PID</TableHead>
                      <TableHead className="text-right">Actions</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {filteredJobs.map((job) => (
                      <TableRow key={job.id}>
                        <TableCell>
                          <code className="rounded bg-muted px-2 py-1 text-xs whitespace-nowrap">
                            {job.id.substring(0, 8)}...
                          </code>
                        </TableCell>
                        <TableCell>
                          <div className="flex items-center gap-2 whitespace-nowrap">
                            <BriefcaseBusiness className="h-4 w-4 text-muted-foreground" />
                            <span className="font-medium">{job.spider}</span>
                          </div>
                        </TableCell>
                        <TableCell>{getStatusBadge(job.status)}</TableCell>
                        <TableCell>
                          <span className="text-sm text-muted-foreground whitespace-nowrap">
                            {format(new Date(job.start_time), "PPp")}
                          </span>
                        </TableCell>
                        <TableCell>
                          {job.pid ? (
                            <code className="text-xs">{job.pid}</code>
                          ) : (
                            <span className="text-xs text-muted-foreground">-</span>
                          )}
                        </TableCell>
                        <TableCell className="text-right">
                          <div className="flex items-center justify-end gap-2">
                            {job.log_url && (
                              <Button
                                variant="ghost"
                                size="sm"
                                asChild
                              >
                                <a
                                  href={job.log_url}
                                  target="_blank"
                                  rel="noopener noreferrer"
                                >
                                  <ExternalLink className="h-4 w-4" />
                                </a>
                              </Button>
                            )}
                            {(job.status === "pending" || job.status === "running") && (
                              <Button
                                variant="ghost"
                                size="sm"
                                onClick={() => {
                                  setSelectedJob(job);
                                  setCancelDialogOpen(true);
                                }}
                              >
                                <XCircle className="h-4 w-4 text-destructive" />
                              </Button>
                            )}
                          </div>
                        </TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              </div>
            ) : (
              <div className="flex flex-col items-center justify-center py-12 text-center">
                <AlertCircle className="mb-4 h-12 w-12 text-muted-foreground" />
                <h3 className="mb-2 text-lg font-semibold">No jobs found</h3>
                <p className="text-sm text-muted-foreground">
                  {statusFilter === "all"
                    ? "No jobs have been scheduled for this project"
                    : `No ${statusFilter} jobs found`}
                </p>
              </div>
            )}
          </CardContent>
        </Card>
      )}

      {!selectedProject && !isProjectsLoading && (
        <Card>
          <CardContent className="flex flex-col items-center justify-center py-12">
            <BriefcaseBusiness className="mb-4 h-12 w-12 text-muted-foreground" />
            <h3 className="mb-2 text-lg font-semibold">Select a project</h3>
            <p className="text-sm text-muted-foreground">
              Choose a project to view its jobs
            </p>
          </CardContent>
        </Card>
      )}

      {/* Cancel Job Dialog */}
      <Dialog open={cancelDialogOpen} onOpenChange={setCancelDialogOpen}>
        <DialogContent className="max-w-[95vw] sm:max-w-[425px]">
          <DialogHeader>
            <DialogTitle>Cancel Job</DialogTitle>
            <DialogDescription>
              Are you sure you want to cancel this job?
              {selectedJob && (
                <div className="mt-2 rounded-lg border p-3">
                  <p className="text-sm">
                    <strong>Spider:</strong> {selectedJob.spider}
                  </p>
                  <p className="text-sm break-all">
                    <strong>Job ID:</strong> <code>{selectedJob.id}</code>
                  </p>
                </div>
              )}
            </DialogDescription>
          </DialogHeader>
          <DialogFooter className="gap-2 sm:gap-0">
            <Button
              variant="outline"
              onClick={() => setCancelDialogOpen(false)}
              className="w-full sm:w-auto"
            >
              No, keep it
            </Button>
            <Button
              variant="destructive"
              onClick={handleCancelJob}
              disabled={cancelJobMutation.isPending}
              className="w-full sm:w-auto"
            >
              {cancelJobMutation.isPending ? "Canceling..." : "Yes, cancel job"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
