"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert";
import { Progress, ProgressLabel, ProgressValue } from "@/components/ui/progress";
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import {
  Sheet,
  SheetTrigger,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetDescription,
} from "@/components/ui/sheet";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Separator } from "@/components/ui/separator";
import { Badge } from "@/components/ui/badge";
import { BookOpen, CheckCircle2, Clock, Pause } from "lucide-react";
import { useActiveTimer } from "@/hooks/use-active-timer";

function formatTime(ms: number): string {
  const totalSeconds = Math.floor(ms / 1000);
  const minutes = Math.floor(totalSeconds / 60);
  const seconds = totalSeconds % 60;
  return `${minutes}:${seconds.toString().padStart(2, "0")}`;
}

const CATEGORIES = [
  "Board Governance",
  "Management Role",
  "Risk Management Process",
  "Third-Party Risk",
  "Incident Disclosure",
  "Strategy Integration",
  "None/Other",
] as const;

const SPECIFICITY_LABELS = [
  "Generic Boilerplate",
  "Sector-Adapted",
  "Firm-Specific",
  "Quantified-Verifiable",
] as const;

interface ParagraphData {
  id: string;
  text: string;
  wordCount: number;
  paragraphIndex: number;
  companyName: string;
  ticker: string | null;
  filingType: string;
  filingDate: string;
  secItem: string;
}

interface ProgressData {
  completed: number;
  total: number;
}

export default function LabelPage() {
  const router = useRouter();
  const [paragraph, setParagraph] = useState<ParagraphData | null>(null);
  const [progress, setProgress] = useState<ProgressData>({ completed: 0, total: 0 });
  const [category, setCategory] = useState<string>("");
  const [specificity, setSpecificity] = useState<number>(0);
  const [notes, setNotes] = useState("");
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [done, setDone] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const timer = useActiveTimer();
  const sessionId = useRef<string>(crypto.randomUUID());
  const notesRef = useRef<HTMLTextAreaElement>(null);

  const fetchNext = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const res = await fetch("/api/label");
      const data = await res.json();

      if (!res.ok) {
        setError(data.error ?? "Failed to load");
        return;
      }

      if (data.redirectToWarmup) {
        router.push("/label/warmup");
        return;
      }

      if (data.done) {
        setDone(true);
        setProgress(data.progress);
        return;
      }

      setParagraph(data.paragraph);
      setProgress(data.progress);
      setCategory("");
      setSpecificity(0);
      setNotes("");
      timer.reset();
    } catch {
      setError("Network error");
    } finally {
      setLoading(false);
    }
  }, [router, timer.reset]);

  useEffect(() => {
    fetchNext();
  }, [fetchNext]);

  const handleSubmit = useCallback(async () => {
    if (!category || !specificity || !paragraph || submitting) return;

    const durationMs = timer.totalMs;
    const activeMs = timer.activeMs;
    setSubmitting(true);

    try {
      const res = await fetch("/api/label", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          paragraphId: paragraph.id,
          contentCategory: category,
          specificityLevel: specificity,
          notes: notes.trim() || undefined,
          sessionId: sessionId.current,
          durationMs,
          activeMs,
        }),
      });

      const data = await res.json();
      if (!res.ok) {
        setError(data.error ?? "Failed to submit");
        return;
      }

      setProgress(data.progress);
      // Immediately fetch next paragraph
      await fetchNext();
    } catch {
      setError("Network error");
    } finally {
      setSubmitting(false);
    }
  }, [category, specificity, paragraph, notes, submitting, fetchNext]);

  // Keyboard shortcuts
  useEffect(() => {
    function handleKeyDown(e: KeyboardEvent) {
      if (e.target instanceof HTMLTextAreaElement) return;
      if (done || loading) return;

      const specKeys: Record<string, number> = { q: 1, w: 2, e: 3, r: 4 };
      if (specKeys[e.key.toLowerCase()]) {
        e.preventDefault();
        setSpecificity(specKeys[e.key.toLowerCase()]);
      } else if (!e.shiftKey && e.key >= "1" && e.key <= "7") {
        e.preventDefault();
        setCategory(CATEGORIES[parseInt(e.key) - 1]);
      } else if (e.key === "Enter" && category && specificity) {
        e.preventDefault();
        handleSubmit();
      } else if (e.key === "n" || e.key === "N") {
        // Focus notes field
        e.preventDefault();
        notesRef.current?.focus();
      }
    }

    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [category, specificity, done, loading, handleSubmit]);

  if (loading && !paragraph) {
    return (
      <div className="flex flex-1 items-center justify-center bg-background">
        <p className="text-muted-foreground">Loading...</p>
      </div>
    );
  }

  if (error) {
    return (
      <div className="flex flex-1 items-center justify-center bg-background">
        <Alert variant="destructive" className="max-w-md">
          <AlertTitle>Error</AlertTitle>
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      </div>
    );
  }

  if (done) {
    return (
      <div className="flex flex-1 items-center justify-center bg-background">
        <Card className="w-full max-w-md text-center">
          <CardHeader>
            <CheckCircle2 className="mx-auto mb-2 size-12 text-green-600" />
            <CardTitle>All Done!</CardTitle>
          </CardHeader>
          <CardContent>
            <p className="text-muted-foreground">
              You have labeled all {progress.total} assigned paragraphs. Thank you!
            </p>
            <Button
              className="mt-6"
              onClick={() => router.push("/dashboard")}
            >
              Back to Dashboard
            </Button>
          </CardContent>
        </Card>
      </div>
    );
  }

  if (!paragraph) return null;

  return (
    <div className="flex flex-1 flex-col bg-background">
      {/* Header bar */}
      <header className="border-b bg-card px-6 py-3">
        <div className="mx-auto flex max-w-5xl items-center justify-between gap-4">
          <div className="flex items-center gap-3 overflow-hidden">
            <span className="truncate font-medium">
              {paragraph.companyName}
              {paragraph.ticker ? ` (${paragraph.ticker})` : ""}
            </span>
            <Badge variant="outline">{paragraph.filingType}</Badge>
            <Badge variant="outline">{paragraph.filingDate}</Badge>
            <Badge variant="outline">{paragraph.secItem}</Badge>
          </div>
          <div className="flex items-center gap-4">
            <div className="flex items-center gap-1.5 text-sm tabular-nums">
              {timer.isIdle ? (
                <Pause className="size-3.5 text-amber-500" />
              ) : (
                <Clock className="size-3.5 text-muted-foreground" />
              )}
              <span className={timer.isIdle ? "text-amber-500" : "text-muted-foreground"}>
                {formatTime(timer.activeMs)}
              </span>
              {timer.isIdle && (
                <span className="text-xs text-amber-500/70">idle</span>
              )}
            </div>
            <Progress
              value={progress.completed}
              max={progress.total}
              className="w-40"
            >
              <ProgressLabel>Progress</ProgressLabel>
              <ProgressValue>
                {() => `${progress.completed} / ${progress.total}`}
              </ProgressValue>
            </Progress>
          </div>
        </div>
      </header>

      {/* Floating codebook button */}
      <CodebookSidebar />

      {/* Main content */}
      <main className="mx-auto flex w-full max-w-5xl flex-1 flex-col gap-6 p-6">
        {/* Paragraph display */}
        <Card>
          <CardContent className="p-6">
            <div className="rounded-lg bg-amber-50 p-6 text-base leading-relaxed dark:bg-amber-950/30">
              {paragraph.text}
            </div>
            <p className="mt-2 text-right text-xs text-muted-foreground">
              {paragraph.wordCount} words
            </p>
          </CardContent>
        </Card>

        {/* Labeling form */}
        <div className="grid gap-6 md:grid-cols-2">
          {/* Content Category */}
          <Card>
            <CardHeader className="pb-3">
              <CardTitle className="text-sm">Content Category</CardTitle>
            </CardHeader>
            <CardContent>
              <RadioGroup value={category} onValueChange={setCategory}>
                {CATEGORIES.map((cat, i) => (
                  <div key={cat} className="flex items-center gap-3">
                    <RadioGroupItem value={cat} id={`cat-${i}`} />
                    <Label
                      htmlFor={`cat-${i}`}
                      className="cursor-pointer text-sm"
                    >
                      {cat}{" "}
                      <kbd className="ml-1 rounded border bg-muted px-1 py-0.5 text-xs text-muted-foreground">
                        {i + 1}
                      </kbd>
                    </Label>
                  </div>
                ))}
              </RadioGroup>
            </CardContent>
          </Card>

          {/* Specificity Level */}
          <Card>
            <CardHeader className="pb-3">
              <CardTitle className="text-sm">Specificity Level</CardTitle>
            </CardHeader>
            <CardContent>
              <RadioGroup
                value={specificity ? String(specificity) : ""}
                onValueChange={(v: string) => setSpecificity(parseInt(v))}
              >
                {SPECIFICITY_LABELS.map((label, i) => (
                  <div key={label} className="flex items-center gap-3">
                    <RadioGroupItem
                      value={String(i + 1)}
                      id={`spec-${i}`}
                    />
                    <Label
                      htmlFor={`spec-${i}`}
                      className="cursor-pointer text-sm"
                    >
                      {label}{" "}
                      <kbd className="ml-1 rounded border bg-muted px-1 py-0.5 text-xs text-muted-foreground">
                        {["Q", "W", "E", "R"][i]}
                      </kbd>
                    </Label>
                  </div>
                ))}
              </RadioGroup>
            </CardContent>
          </Card>
        </div>

        {/* Submit button */}
        <Button
          onClick={handleSubmit}
          disabled={!category || !specificity || submitting}
          className="w-full"
          size="lg"
        >
          {submitting ? "Submitting..." : "Submit"}{" "}
          <kbd className="ml-2 rounded border bg-primary-foreground/20 px-1.5 py-0.5 text-xs">
            Enter
          </kbd>
        </Button>

        {/* Notes */}
        <Card>
          <CardContent className="p-4">
            <Label htmlFor="notes" className="mb-2 text-sm">
              Notes (optional){" "}
              <kbd className="ml-1 rounded border bg-muted px-1 py-0.5 text-xs text-muted-foreground">
                N
              </kbd>
            </Label>
            <Textarea
              ref={notesRef}
              id="notes"
              value={notes}
              onChange={(e) => setNotes(e.target.value)}
              placeholder="Any observations, edge cases, or uncertainty..."
              rows={2}
              className="mt-2 resize-none"
            />
          </CardContent>
        </Card>
      </main>
    </div>
  );
}

function CodebookSidebar() {
  return (
    <div className="fixed bottom-6 right-6 z-50">
      <Sheet>
        <SheetTrigger className="inline-flex size-14 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-lg hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring">
          <BookOpen className="size-6" />
        </SheetTrigger>
        <SheetContent side="right" className="w-[420px] sm:max-w-[420px]">
          <SheetHeader>
            <SheetTitle>Labeling Codebook</SheetTitle>
            <SheetDescription>Quick reference for categories and specificity levels</SheetDescription>
          </SheetHeader>
          <ScrollArea className="flex-1 px-4 pb-4">
            <div className="space-y-6">
            {/* Categories */}
            <section>
              <h3 className="mb-3 text-sm font-semibold uppercase tracking-wider text-muted-foreground">
                Content Categories
              </h3>
              <div className="space-y-3">
                <CategoryDef
                  num={1}
                  name="Board Governance"
                  desc="Board/committee oversight of cyber risk. The board or a board committee is the grammatical subject performing the primary action."
                  examples="Board receives reports, Audit Committee oversees, directors review"
                  notList="CISO reports TO board (Management Role), board mentioned only in passing"
                />
                <CategoryDef
                  num={2}
                  name="Management Role"
                  desc="Named officers or management teams responsible for cybersecurity. A specific person or management function is the grammatical subject."
                  examples="CISO leads program, VP of Security manages, management team implements"
                  notList="Board delegates to CISO (Board Governance if board is subject)"
                />
                <CategoryDef
                  num={3}
                  name="Risk Management Process"
                  desc="Internal cybersecurity program mechanics: frameworks, assessments, controls, training, monitoring."
                  examples="We maintain a program, NIST framework, penetration testing, employee training"
                  notList="Vendor assessments (Third-Party Risk), incident response actions (Incident Disclosure)"
                />
                <CategoryDef
                  num={4}
                  name="Third-Party Risk"
                  desc="Oversight of external parties' cybersecurity: vendors, suppliers, service providers, contractors."
                  examples="Vendor assessments, third-party audits, supply chain monitoring, SOC 2 requirements"
                  notList="Internal program using third-party tools (Risk Management Process)"
                />
                <CategoryDef
                  num={5}
                  name="Incident Disclosure"
                  desc="Description of what happened in a cybersecurity incident: timeline, impact, response, remediation."
                  examples="We detected unauthorized access, breach affected N records, incident response activated"
                  notList="Generic incident response plans (Risk Management Process), hypothetical incidents"
                />
                <CategoryDef
                  num={6}
                  name="Strategy Integration"
                  desc="Business/financial consequences of cyber risk: budget, insurance, M&A due diligence, competitive impact, regulatory strategy."
                  examples="Cyber budget increased, insurance coverage, risk factors, financial impact"
                  notList="Technical program costs (Risk Management Process)"
                />
                <CategoryDef
                  num={7}
                  name="None/Other"
                  desc="Does not fit any of the above categories. Generic corporate language, non-cyber content, or ambiguous."
                />
              </div>
            </section>

            <Separator />

            {/* Specificity */}
            <section>
              <h3 className="mb-3 text-sm font-semibold uppercase tracking-wider text-muted-foreground">
                Specificity Levels
              </h3>
              <div className="space-y-3">
                <SpecDef
                  level={1}
                  name="Generic Boilerplate"
                  desc="Could appear in any company's filing unchanged. No named frameworks, tools, people, dates, or quantities."
                />
                <SpecDef
                  level={2}
                  name="Sector-Adapted"
                  desc="Names a recognized standard or sector practice (e.g., NIST, SOC 2, PCI DSS) but nothing firm-specific."
                />
                <SpecDef
                  level={3}
                  name="Firm-Specific"
                  desc="Contains at least one fact from the IS list unique to this company: cybersecurity-specific titles (CISO, CTO), named tools/vendors, specific dates, named committees."
                />
                <SpecDef
                  level={4}
                  name="Quantified-Verifiable"
                  desc="Contains 2+ hard verifiable facts: specific dates, dollar amounts, percentages, headcounts, named third parties with specifics."
                />
              </div>
            </section>

            <Separator />

            {/* Decision rules */}
            <section>
              <h3 className="mb-3 text-sm font-semibold uppercase tracking-wider text-muted-foreground">
                Key Decision Rules
              </h3>
              <div className="space-y-2 text-sm">
                <Rule title="Board vs Management">
                  Who is the grammatical subject? Board/committee = Board
                  Governance. Named officer/team = Management Role.
                </Rule>
                <Rule title="Person vs Function">
                  Is the paragraph about the person (credentials, background,
                  reporting lines) or the function (program activities, tools)?
                  Person → Management Role. Function → Risk Management Process.
                </Rule>
                <Rule title="QV threshold">
                  Need 2+ independently verifiable facts (dates, dollar amounts,
                  named firms, headcounts) for Specificity 4.
                </Rule>
                <Rule title="Materiality disclaimers">
                  Any "materially affected" assessment = Strategy Integration,
                  even if boilerplate. Pure cross-reference with no materiality
                  conclusion = None/Other.
                </Rule>
                <Rule title="Dual-topic paragraphs">
                  Choose the category whose content occupies the majority of the
                  paragraph — the primary communicative purpose.
                </Rule>
              </div>
            </section>
            <Separator className="my-4" />
            <a
              href="/codebook"
              target="_blank"
              rel="noopener noreferrer"
              className="inline-flex items-center text-sm font-medium text-primary hover:underline"
            >
              Open full codebook reference →
            </a>
            </div>
          </ScrollArea>
        </SheetContent>
      </Sheet>
    </div>
  );
}

function CategoryDef({
  num,
  name,
  desc,
  examples,
  notList,
}: {
  num: number;
  name: string;
  desc: string;
  examples?: string;
  notList?: string;
}) {
  return (
    <div className="rounded-md border p-3">
      <div className="flex items-center gap-2">
        <Badge variant="outline" className="font-mono text-xs">
          {num}
        </Badge>
        <span className="font-medium text-sm">{name}</span>
      </div>
      <p className="mt-1.5 text-xs text-muted-foreground leading-relaxed">{desc}</p>
      {examples && (
        <p className="mt-1 text-xs">
          <span className="font-medium text-green-700 dark:text-green-400">IS: </span>
          {examples}
        </p>
      )}
      {notList && (
        <p className="mt-0.5 text-xs">
          <span className="font-medium text-red-700 dark:text-red-400">NOT: </span>
          {notList}
        </p>
      )}
    </div>
  );
}

function SpecDef({
  level,
  name,
  desc,
}: {
  level: number;
  name: string;
  desc: string;
}) {
  return (
    <div className="rounded-md border p-3">
      <div className="flex items-center gap-2">
        <Badge variant="outline" className="font-mono text-xs">
          {level}
        </Badge>
        <span className="font-medium text-sm">{name}</span>
      </div>
      <p className="mt-1.5 text-xs text-muted-foreground leading-relaxed">{desc}</p>
    </div>
  );
}

function Rule({
  title,
  children,
}: {
  title: string;
  children: React.ReactNode;
}) {
  return (
    <div className="rounded-md bg-muted/50 p-2.5">
      <span className="font-medium">{title}: </span>
      <span className="text-muted-foreground">{children}</span>
    </div>
  );
}
