/**
 * UK Visa Jobs search page.
 */

import React, { useEffect, useMemo, useState } from "react";
import {
  ArrowLeft,
  Briefcase,
  Calendar,
  ChevronLeft,
  ChevronRight,
  Clock,
  Database,
  DollarSign,
  ExternalLink,
  GraduationCap,
  Loader2,
  MapPin,
  Search,
  Settings,
} from "lucide-react";
import { Link } from "react-router-dom";
import { toast } from "sonner";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Separator } from "@/components/ui/separator";
import { Drawer, DrawerClose, DrawerContent } from "@/components/ui/drawer";
import { cn } from "@/lib/utils";
import * as api from "../api";
import type { CreateJobInput } from "../../shared/types";

const formatDate = (dateStr?: string | null) => {
  if (!dateStr) return null;
  try {
    return new Date(dateStr).toLocaleDateString("en-GB", {
      day: "numeric",
      month: "short",
      year: "numeric",
    });
  } catch {
    return dateStr;
  }
};

const formatDateTime = (dateStr?: string | null) => {
  if (!dateStr) return null;
  try {
    const normalized = dateStr.includes("T") ? dateStr : dateStr.replace(" ", "T");
    const parsed = new Date(normalized);
    if (Number.isNaN(parsed.getTime())) return dateStr;
    const date = parsed.toLocaleDateString("en-GB", {
      day: "numeric",
      month: "short",
      year: "numeric",
    });
    const time = parsed.toLocaleTimeString("en-GB", {
      hour: "2-digit",
      minute: "2-digit",
    });
    return `${date} ${time}`;
  } catch {
    return dateStr;
  }
};

const stripHtml = (value: string) => value.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim();

const clampText = (value: string, max = 160) => (value.length > max ? `${value.slice(0, max).trim()}...` : value);

const jobKey = (job: CreateJobInput) => job.sourceJobId || job.jobUrl;

export const UkVisaJobsPage: React.FC = () => {
  const [searchTermInput, setSearchTermInput] = useState("");
  const [activeSearchTerm, setActiveSearchTerm] = useState<string | null>(null);
  const [results, setResults] = useState<CreateJobInput[]>([]);
  const [selectedJobId, setSelectedJobId] = useState<string | null>(null);
  const [selectedJobIds, setSelectedJobIds] = useState<Set<string>>(new Set());
  const [isSearching, setIsSearching] = useState(false);
  const [isImporting, setIsImporting] = useState(false);
  const [lastRunAt, setLastRunAt] = useState<string | null>(null);
  const [lastSearchTerm, setLastSearchTerm] = useState<string | null>(null);
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(15);
  const [totalJobs, setTotalJobs] = useState(0);
  const [totalPages, setTotalPages] = useState(1);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [isDetailDrawerOpen, setIsDetailDrawerOpen] = useState(false);
  const [isDesktop, setIsDesktop] = useState(
    () => (typeof window !== "undefined" ? window.matchMedia("(min-width: 1024px)").matches : false),
  );

  useEffect(() => {
    if (results.length === 0) {
      setSelectedJobId(null);
      return;
    }
    const firstKey = jobKey(results[0]);
    if (!selectedJobId || !results.some((job) => jobKey(job) === selectedJobId)) {
      setSelectedJobId(firstKey);
    }
  }, [results, selectedJobId]);

  useEffect(() => {
    if (!selectedJobId) {
      setIsDetailDrawerOpen(false);
    }
  }, [selectedJobId]);

  useEffect(() => {
    if (typeof window === "undefined") return;
    const media = window.matchMedia("(min-width: 1024px)");
    const handleChange = () => setIsDesktop(media.matches);
    handleChange();
    if (media.addEventListener) {
      media.addEventListener("change", handleChange);
      return () => media.removeEventListener("change", handleChange);
    }
    media.addListener(handleChange);
    return () => media.removeListener(handleChange);
  }, []);

  useEffect(() => {
    if (isDesktop && isDetailDrawerOpen) {
      setIsDetailDrawerOpen(false);
    }
  }, [isDesktop, isDetailDrawerOpen]);

  useEffect(() => {
    setSelectedJobIds(new Set());
  }, [results]);

  const selectedJob = useMemo(
    () => (selectedJobId ? results.find((job) => jobKey(job) === selectedJobId) ?? null : null),
    [results, selectedJobId],
  );

  const summaryCounts = useMemo(() => {
    const startIndex = totalJobs === 0 ? 0 : (page - 1) * pageSize + 1;
    const endIndex = totalJobs === 0 ? 0 : Math.min(page * pageSize, totalJobs);
    return {
      startIndex,
      endIndex,
    };
  }, [page, pageSize, totalJobs]);

  const runSearch = async ({ term, pageNumber }: { term: string | null; pageNumber: number }) => {
    try {
      setIsSearching(true);
      setErrorMessage(null);
      const response = await api.searchUkVisaJobs({
        searchTerm: term ?? undefined,
        page: pageNumber,
      });
      setResults(response.jobs);
      setPage(response.page);
      setPageSize(response.pageSize);
      setTotalJobs(response.totalJobs);
      setTotalPages(response.totalPages);
      setLastRunAt(new Date().toISOString());
      if (response.jobs.length === 0) {
        toast.message("No UK Visa Jobs found for this search.");
      }
    } catch (error) {
      const message = error instanceof Error ? error.message : "UK Visa Jobs search failed";
      setErrorMessage(message);
      toast.error(message);
    } finally {
      setIsSearching(false);
    }
  };

  const handleSearch = async (event: React.FormEvent) => {
    event.preventDefault();
    setErrorMessage(null);

    const terms = searchTermInput
      .split(/[\n,]+/)
      .map((term) => term.trim())
      .filter(Boolean);
    const term = terms[0] || null;

    if (terms.length > 1) {
      toast.message("Using the first term for pagination.");
    }

    setActiveSearchTerm(term);
    setLastSearchTerm(term);
    setPage(1);

    await runSearch({ term, pageNumber: 1 });
  };

  const handlePageChange = (nextPage: number) => {
    if (isSearching) return;
    if (nextPage < 1 || nextPage > totalPages) return;
    setPage(nextPage);
    void runSearch({ term: activeSearchTerm, pageNumber: nextPage });
  };

  const handleImportSelected = async () => {
    const selectedJobs = results.filter((job) => selectedJobIds.has(jobKey(job)));
    if (selectedJobs.length === 0) return;

    try {
      setIsImporting(true);
      const response = await api.importUkVisaJobs({ jobs: selectedJobs });
      toast.success(`Imported ${response.created} jobs`, {
        description: response.skipped ? `${response.skipped} skipped (duplicates)` : undefined,
      });
      setSelectedJobIds(new Set());
    } catch (error) {
      const message = error instanceof Error ? error.message : "Failed to import jobs";
      toast.error(message);
    } finally {
      setIsImporting(false);
    }
  };

  const selectedDescription = useMemo(() => {
    if (!selectedJob?.jobDescription) return "No description available.";
    const cleaned = stripHtml(selectedJob.jobDescription);
    return cleaned || "No description available.";
  }, [selectedJob]);

  const selectedJobLink = selectedJob ? selectedJob.applicationLink || selectedJob.jobUrl : "#";
  const selectedDeadline = selectedJob ? formatDate(selectedJob.deadline) : null;
  const selectedPosted = selectedJob ? formatDate(selectedJob.datePosted) : null;
  const selectedCount = selectedJobIds.size;
  const allSelected = results.length > 0 && results.every((job) => selectedJobIds.has(jobKey(job)));
  const selectAllState = allSelected ? true : selectedCount > 0 ? "indeterminate" : false;
  const canGoPrev = page > 1;
  const canGoNext = page < totalPages;

  const handleSelectJob = (jobId: string) => {
    setSelectedJobId(jobId);
    if (!isDesktop) {
      setIsDetailDrawerOpen(true);
    }
  };

  const detailPanelContent = !selectedJob ? (
    <div className="flex h-full flex-col items-center justify-center gap-2 text-center">
      <div className="text-base font-semibold">Select a job</div>
      <p className="text-sm text-muted-foreground">Pick a job from the list to inspect details.</p>
    </div>
  ) : (
    <div className="space-y-4">
      <div className="flex flex-wrap items-start justify-between gap-3">
        <div className="min-w-0">
          <div className="truncate text-base font-semibold">{selectedJob.title}</div>
          <div className="text-sm text-muted-foreground">{selectedJob.employer}</div>
        </div>
        <Badge variant="outline" className="uppercase tracking-wide">
          UK Visa Jobs
        </Badge>
      </div>

      <div className="flex flex-wrap items-center gap-3 text-xs text-muted-foreground">
        {selectedJob.location && (
          <span className="flex items-center gap-1">
            <MapPin className="h-3.5 w-3.5" />
            {selectedJob.location}
          </span>
        )}
        {selectedDeadline && (
          <span className="flex items-center gap-1">
            <Calendar className="h-3.5 w-3.5" />
            {selectedDeadline}
          </span>
        )}
        {selectedPosted && (
          <span className="flex items-center gap-1">
            <Clock className="h-3.5 w-3.5" />
            Posted {selectedPosted}
          </span>
        )}
        {selectedJob.salary && (
          <span className="flex items-center gap-1">
            <DollarSign className="h-3.5 w-3.5" />
            {selectedJob.salary}
          </span>
        )}
        {selectedJob.degreeRequired && (
          <span className="flex items-center gap-1">
            <GraduationCap className="h-3.5 w-3.5" />
            {selectedJob.degreeRequired}
          </span>
        )}
      </div>

      <div className="grid gap-3 text-sm sm:grid-cols-2">
        <div>
          <div className="text-xs text-muted-foreground">Job type</div>
          <div className="font-medium">{selectedJob.jobType || "Not set"}</div>
        </div>
        <div>
          <div className="text-xs text-muted-foreground">Job level</div>
          <div className="font-medium">{selectedJob.jobLevel || "Not set"}</div>
        </div>
        <div>
          <div className="text-xs text-muted-foreground">Location</div>
          <div className="font-medium">{selectedJob.location || "Not set"}</div>
        </div>
        <div>
          <div className="text-xs text-muted-foreground">Deadline</div>
          <div className="font-medium">{selectedDeadline || "Not set"}</div>
        </div>
      </div>

      <Separator />

      <Button asChild size="sm" variant="outline" className="w-full gap-2 sm:w-auto">
        <a href={selectedJobLink} target="_blank" rel="noopener noreferrer">
          <ExternalLink className="h-4 w-4" />
          View job
        </a>
      </Button>

      <div className="space-y-2">
        <div className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
          Description
        </div>
        <div className="rounded-lg border border-border/60 bg-muted/10 p-3 text-sm text-muted-foreground whitespace-pre-wrap">
          {selectedDescription}
        </div>
      </div>
    </div>
  );

  return (
    <>
      <header className="sticky top-0 z-40 border-b bg-background/80 backdrop-blur supports-[backdrop-filter]:bg-background/60">
        <div className="container mx-auto flex max-w-7xl flex-col gap-3 px-4 py-4 sm:flex-row sm:items-center sm:justify-between">
          <div className="flex min-w-0 flex-wrap items-center gap-3">
            <div className="flex h-9 w-9 items-center justify-center rounded-lg border border-border/60 bg-muted/30">
              <Briefcase className="h-4 w-4 text-muted-foreground" />
            </div>
            <div className="min-w-0 leading-tight">
              <div className="text-sm font-semibold tracking-tight">UK Visa Jobs</div>
              <div className="text-xs text-muted-foreground">Live search console</div>
            </div>
            <Badge variant="outline" className="uppercase tracking-wide">
              API search
            </Badge>
          </div>

          <div className="flex w-full items-center gap-2 sm:w-auto sm:justify-end">
            <Button asChild variant="ghost" size="icon" aria-label="Back to orchestrator">
              <Link to="/">
                <ArrowLeft className="h-4 w-4" />
              </Link>
            </Button>
            <Button asChild variant="ghost" size="icon" aria-label="Settings">
              <Link to="/settings">
                <Settings className="h-4 w-4" />
              </Link>
            </Button>
          </div>
        </div>
      </header>

      <main className="container mx-auto max-w-7xl space-y-6 px-4 py-6 pb-12">
        <section className="rounded-xl border border-border/60 bg-card/40 p-4">
          <form className="grid gap-4 md:grid-cols-[minmax(0,1fr)_160px]" onSubmit={handleSearch}>
            <div className="space-y-2">
              <label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                Search term
              </label>
              <Input
                value={searchTermInput}
                onChange={(event) => setSearchTermInput(event.target.value)}
                placeholder="e.g. data analyst"
                className="h-10"
              />
              <p className="text-xs text-muted-foreground">
                Single keyword or phrase. Leave blank to fetch the newest jobs.
              </p>
            </div>

            <div className="flex items-end">
              <Button type="submit" className="h-10 w-full gap-2" disabled={isSearching}>
                {isSearching ? <Loader2 className="h-4 w-4 animate-spin" /> : <Search className="h-4 w-4" />}
                {isSearching ? "Searching..." : "Search"}
              </Button>
            </div>
          </form>

          {errorMessage && (
            <div className="mt-4 rounded-lg border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive">
              {errorMessage}
            </div>
          )}

          <Separator className="my-4" />

          <div className="flex flex-col gap-2 text-xs text-muted-foreground sm:flex-row sm:items-center sm:justify-between">
            <div>
              Last run: {lastRunAt ? formatDateTime(lastRunAt) : "No searches yet"}
            </div>
            <div className="flex flex-wrap items-center gap-2">
              <Badge variant="outline" className="text-xs">
                {totalJobs} total
              </Badge>
              <Badge variant="outline" className="text-xs">
                {results.length} on page
              </Badge>
              <span>
                Page {page} of {totalPages}
              </span>
              {lastSearchTerm && <span className="truncate">Term: {lastSearchTerm}</span>}
            </div>
          </div>
        </section>

        <section className="grid gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(0,420px)]">
          <div className="relative min-w-0 rounded-xl border border-border/60 bg-card/40">
            {isSearching && results.length > 0 && (
              <div className="absolute inset-0 z-10 flex flex-col items-center justify-center gap-2 rounded-xl bg-background/70 text-sm text-muted-foreground backdrop-blur-sm">
                <Loader2 className="h-5 w-5 animate-spin" />
                <span>Fetching UK Visa Jobs...</span>
              </div>
            )}
            {results.length === 0 ? (
              <div className="flex flex-col items-center justify-center gap-2 px-6 py-12 text-center">
                {isSearching ? (
                  <>
                    <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
                    <div className="text-base font-semibold">Searching...</div>
                    <p className="max-w-md text-sm text-muted-foreground">
                      Fetching fresh UK Visa Jobs listings.
                    </p>
                  </>
                ) : (
                  <>
                    <div className="text-base font-semibold">No results yet</div>
                    <p className="max-w-md text-sm text-muted-foreground">
                      Run a search to fetch fresh UK Visa Jobs listings.
                    </p>
                  </>
                )}
              </div>
            ) : (
              <>
                <div className="flex flex-wrap items-center justify-between gap-3 border-b border-border/60 px-4 py-3 text-xs text-muted-foreground">
                  <div className="flex items-center gap-2">
                    <Checkbox
                      checked={selectAllState}
                      onCheckedChange={(checked) => {
                        if (checked === true) {
                          setSelectedJobIds(new Set(results.map((job) => jobKey(job))));
                        } else {
                          setSelectedJobIds(new Set());
                        }
                      }}
                      aria-label="Select all jobs on this page"
                    />
                    <span>Select page</span>
                    <Separator orientation="vertical" className="h-4" />
                    <span>{selectedCount} selected</span>
                  </div>
                  <Button
                    variant="outline"
                    size="sm"
                    className="w-full gap-2 sm:w-auto"
                    onClick={handleImportSelected}
                    disabled={selectedCount === 0 || isImporting}
                  >
                    {isImporting ? <Loader2 className="h-4 w-4 animate-spin" /> : <Database className="h-4 w-4" />}
                    {isImporting ? "Importing..." : "Import to DB"}
                  </Button>
                </div>
                <div className="divide-y divide-border/60">
                  {results.map((job) => {
                    const key = jobKey(job);
                    const isSelected = key === selectedJobId;
                    const isChecked = selectedJobIds.has(key);
                    const description = job.jobDescription ? clampText(stripHtml(job.jobDescription)) : "No description.";

                    return (
                      <div
                        key={key}
                        role="button"
                        tabIndex={0}
                        onClick={() => handleSelectJob(key)}
                        onKeyDown={(event) => {
                          if (event.key === "Enter" || event.key === " ") {
                            event.preventDefault();
                            handleSelectJob(key);
                          }
                        }}
                        className={cn(
                          "flex w-full items-start gap-4 px-4 py-3 text-left transition-colors",
                          isSelected ? "bg-muted/40" : "hover:bg-muted/30",
                        )}
                        aria-pressed={isSelected}
                      >
                        <div
                          className="mt-1"
                          onClick={(event) => event.stopPropagation()}
                          onKeyDown={(event) => event.stopPropagation()}
                          role="presentation"
                        >
                          <Checkbox
                            checked={isChecked}
                            onCheckedChange={(checked) => {
                              setSelectedJobIds((current) => {
                                const next = new Set(current);
                                if (checked) {
                                  next.add(key);
                                } else {
                                  next.delete(key);
                                }
                                return next;
                              });
                            }}
                            aria-label={`Select ${job.title}`}
                          />
                        </div>
                        <span className="mt-1 flex h-8 w-8 items-center justify-center rounded-lg border border-border/60 bg-muted/30">
                          <Briefcase className="h-4 w-4 text-muted-foreground" />
                        </span>
                        <div className="min-w-0 flex-1 space-y-2">
                          <div className="space-y-1">
                            <div className="truncate text-sm font-semibold">{job.title}</div>
                            <div className="text-xs text-muted-foreground">{job.employer}</div>
                          </div>
                          <div className="text-xs text-muted-foreground">{description}</div>
                          <div className="flex flex-wrap items-center gap-2 text-xs text-muted-foreground">
                            {job.location && (
                              <span className="flex items-center gap-1">
                                <MapPin className="h-3.5 w-3.5" />
                                {job.location}
                              </span>
                            )}
                            {job.salary && (
                              <span className="flex items-center gap-1">
                                <DollarSign className="h-3.5 w-3.5" />
                                {job.salary}
                              </span>
                            )}
                            {job.deadline && (
                              <span className="flex items-center gap-1">
                                <Calendar className="h-3.5 w-3.5" />
                                {formatDate(job.deadline)}
                              </span>
                            )}
                          </div>
                          <div className="flex flex-wrap gap-2">
                            {job.jobType && (
                              <Badge variant="outline" className="text-[11px] uppercase tracking-wide">
                                {job.jobType}
                              </Badge>
                            )}
                            {job.jobLevel && (
                              <Badge variant="outline" className="text-[11px] uppercase tracking-wide">
                                {job.jobLevel}
                              </Badge>
                            )}
                          </div>
                        </div>
                      </div>
                    );
                  })}
                </div>
                <div className="flex flex-wrap items-center justify-between gap-3 border-t border-border/60 px-4 py-3 text-xs text-muted-foreground">
                  <span>
                    Showing {summaryCounts.startIndex}-{summaryCounts.endIndex} of {totalJobs}
                  </span>
                  <div className="flex flex-wrap items-center gap-2">
                    <Button
                      variant="outline"
                      size="sm"
                      className="h-8 gap-1"
                      onClick={() => handlePageChange(page - 1)}
                      disabled={!canGoPrev || isSearching}
                    >
                      <ChevronLeft className="h-4 w-4" />
                      Prev
                    </Button>
                    <span>
                      Page {page} of {totalPages}
                    </span>
                    <Button
                      variant="outline"
                      size="sm"
                      className="h-8 gap-1"
                      onClick={() => handlePageChange(page + 1)}
                      disabled={!canGoNext || isSearching}
                    >
                      Next
                      <ChevronRight className="h-4 w-4" />
                    </Button>
                  </div>
                </div>
              </>
            )}
          </div>

          <div className="min-w-0 rounded-xl border border-border/60 bg-card/40 p-4 lg:sticky lg:top-24 lg:self-start hidden lg:block">
            {detailPanelContent}
          </div>
        </section>
      </main>

      <Drawer open={isDetailDrawerOpen} onOpenChange={setIsDetailDrawerOpen}>
        <DrawerContent className="max-h-[90vh]">
          <div className="flex items-center justify-between px-4 pt-2">
            <div className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">Job details</div>
            <DrawerClose asChild>
              <Button variant="ghost" size="sm" className="h-8 px-2 text-xs">
                Close
              </Button>
            </DrawerClose>
          </div>
          <div className="max-h-[calc(90vh-3.5rem)] overflow-y-auto px-4 pb-6 pt-3">
            {detailPanelContent}
          </div>
        </DrawerContent>
      </Drawer>
    </>
  );
};
