import { useState, useRef } from "react";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
  Search, Upload, FileText, Video, Link2, Download, Trash2,
  CheckCircle2, Clock, XCircle, Loader2, BookOpen, Music, Image,
  Library, Plus, CalendarDays, X,
} from "lucide-react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { resourcesService } from "@/services/resources.service";
import { describeApiError } from "@/lib/api-client";
import { coursewareService } from "@/services/courseware.service";
import { taxonomyService } from "@/services/taxonomy.service";
import { useToast } from "@/hooks/use-toast";
import { TaxonomyCascade } from "@/components/TaxonomyCascade";
import type { Resource, ResourceTag } from "@/types";

const statusBadge: Record<string, { variant: "default" | "secondary" | "destructive"; icon: React.ReactNode }> = {
  approved: { variant: "default", icon: <CheckCircle2 className="h-3 w-3 mr-1" /> },
  pending: { variant: "secondary", icon: <Clock className="h-3 w-3 mr-1" /> },
  rejected: { variant: "destructive", icon: <XCircle className="h-3 w-3 mr-1" /> },
};

const typeIcons: Record<string, React.ReactNode> = {
  pdf: <FileText className="h-4 w-4 text-red-500" />,
  video: <Video className="h-4 w-4 text-blue-500" />,
  link: <Link2 className="h-4 w-4 text-green-500" />,
  document: <FileText className="h-4 w-4 text-orange-500" />,
  interactive: <FileText className="h-4 w-4 text-purple-500" />,
  article: <FileText className="h-4 w-4 text-indigo-500" />,
  audio: <Music className="h-4 w-4 text-yellow-500" />,
  image: <Image className="h-4 w-4 text-pink-500" />,
};

interface CourseMaterialItem {
  id: number;
  name: string;
  type: string;
  course_name: string;
  chapter_name: string;
  source: string;
  file_url: string | null;
  url: string | null;
  description: string | null;
  course_id: number;
}

export default function TeacherLibrary() {
  const { toast } = useToast();
  const qc = useQueryClient();

  const [search, setSearch] = useState("");
  const [typeFilter, setTypeFilter] = useState("all");
  const [subjectFilter, setSubjectFilter] = useState<string>("all");
  const [tagFilter, setTagFilter] = useState<string>("all");
  const [dateFrom, setDateFrom] = useState("");
  const [dateTo, setDateTo] = useState("");
  const [activeTab, setActiveTab] = useState("all");

  const [showUpload, setShowUpload] = useState(false);
  const [uploadType, setUploadType] = useState("pdf");
  const [uploadSubjectId, setUploadSubjectId] = useState<string>("none");
  const [uploadDomainId, setUploadDomainId] = useState<string>("none");
  const [uploadTopicIds, setUploadTopicIds] = useState<number[]>([]);
  const [uploadObjectiveIds, setUploadObjectiveIds] = useState<number[]>([]);
  const [uploadTagIds, setUploadTagIds] = useState<number[]>([]);
  const fileRef = useRef<HTMLInputElement>(null);

  const { data: subjects } = useQuery({
    queryKey: ["taxonomy", "subjects"],
    queryFn: () => taxonomyService.listSubjects(),
  });

  const { data: tags } = useQuery({
    queryKey: ["resource-tags"],
    queryFn: () => resourcesService.listTags(),
  });

  const { data: resourcesData, isLoading: loadingResources } = useQuery({
    queryKey: ["resources", "list", { search, resource_type: typeFilter === "all" ? undefined : typeFilter, subject_id: subjectFilter === "all" ? undefined : subjectFilter, tag_id: tagFilter === "all" ? undefined : tagFilter, date_from: dateFrom || undefined, date_to: dateTo || undefined }],
    queryFn: () => resourcesService.list({
      search: search || undefined,
      resource_type: typeFilter === "all" ? undefined : typeFilter,
      subject_id: subjectFilter === "all" ? undefined : Number(subjectFilter),
      tag_id: tagFilter === "all" ? undefined : Number(tagFilter),
      date_from: dateFrom || undefined,
      date_to: dateTo || undefined,
    }),
  });
  const resources = resourcesData?.items ?? [];

  const { data: materialsData, isLoading: loadingMaterials } = useQuery({
    queryKey: ["materials", "search", { search, type: typeFilter }],
    queryFn: () => coursewareService.searchMaterials({
      search: search || undefined,
      type: typeFilter === "all" ? undefined : typeFilter,
    }),
  });
  const courseMaterials = materialsData?.items ?? [];

  const uploadMutation = useMutation({
    mutationFn: (formData: FormData) => resourcesService.upload(formData),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["resources"] });
      toast({ title: "Resource uploaded successfully" });
      setShowUpload(false);
      setUploadTagIds([]);
      setUploadSubjectId("none");
      setUploadDomainId("none");
      setUploadTopicIds([]);
      setUploadObjectiveIds([]);
    },
    onError: (err) => {
      toast({
        title: "Upload failed",
        description: describeApiError(err, "Upload failed", "file"),
        variant: "destructive",
      });
    },
  });

  const deleteMutation = useMutation({
    mutationFn: (id: number) => resourcesService.delete(id),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ["resources"] }); toast({ title: "Resource deleted" }); },
    onError: () => toast({ title: "Error", description: "Delete failed", variant: "destructive" }),
  });

  const handleUpload = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);
    if (uploadTagIds.length > 0) formData.set("tag_ids", uploadTagIds.join(","));
    if (uploadDomainId !== "none") formData.set("domain_id", uploadDomainId);
    if (uploadTopicIds.length > 0) formData.set("topic_ids", uploadTopicIds.join(","));
    if (uploadObjectiveIds.length > 0) formData.set("learning_objective_ids", uploadObjectiveIds.join(","));
    uploadMutation.mutate(formData);
  };

  const toggleUploadTag = (id: number) => {
    setUploadTagIds((prev) => prev.includes(id) ? prev.filter((t) => t !== id) : [...prev, id]);
  };

  const clearFilters = () => {
    setSearch(""); setTypeFilter("all"); setSubjectFilter("all");
    setTagFilter("all"); setDateFrom(""); setDateTo("");
  };
  const hasActiveFilters = search || typeFilter !== "all" || subjectFilter !== "all" || tagFilter !== "all" || dateFrom || dateTo;

  const isLoading = loadingResources || loadingMaterials;

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

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold flex items-center gap-2">
            <Library className="h-6 w-6" /> Resource Library
          </h1>
          <p className="text-muted-foreground">Browse shared resources and your course materials. Upload new content or pick existing resources when building courses.</p>
        </div>
        <Button onClick={() => setShowUpload(true)}>
          <Upload className="mr-2 h-4 w-4" /> Upload Resource
        </Button>
      </div>

      {/* Stats */}
      <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
        <Card className="cursor-pointer hover:shadow-md transition-shadow" onClick={() => setActiveTab("all")}>
          <CardContent className="pt-6 flex items-center gap-4">
            <div className="p-3 rounded-full bg-primary/10"><Library className="h-5 w-5 text-primary" /></div>
            <div>
              <p className="text-2xl font-bold">{resources.length + courseMaterials.length}</p>
              <p className="text-sm text-muted-foreground">Total Resources</p>
            </div>
          </CardContent>
        </Card>
        <Card className="cursor-pointer hover:shadow-md transition-shadow" onClick={() => setActiveTab("library")}>
          <CardContent className="pt-6 flex items-center gap-4">
            <div className="p-3 rounded-full bg-blue-500/10"><FileText className="h-5 w-5 text-blue-500" /></div>
            <div>
              <p className="text-2xl font-bold">{resources.length}</p>
              <p className="text-sm text-muted-foreground">Shared Library</p>
            </div>
          </CardContent>
        </Card>
        <Card className="cursor-pointer hover:shadow-md transition-shadow" onClick={() => setActiveTab("materials")}>
          <CardContent className="pt-6 flex items-center gap-4">
            <div className="p-3 rounded-full bg-green-500/10"><BookOpen className="h-5 w-5 text-green-500" /></div>
            <div>
              <p className="text-2xl font-bold">{courseMaterials.length}</p>
              <p className="text-sm text-muted-foreground">Course Materials</p>
            </div>
          </CardContent>
        </Card>
      </div>

      {/* Filters + Table */}
      <Card>
        <CardHeader className="space-y-3">
          <div className="flex items-center gap-3 flex-wrap">
            <div className="relative flex-1 min-w-[200px]">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
              <Input placeholder="Search resources…" value={search} onChange={e => setSearch(e.target.value)} className="pl-9" />
            </div>
            <Select value={subjectFilter} onValueChange={setSubjectFilter}>
              <SelectTrigger className="w-[150px]"><SelectValue placeholder="Subject" /></SelectTrigger>
              <SelectContent>
                <SelectItem value="all">All Subjects</SelectItem>
                {(subjects ?? []).map((s) => (
                  <SelectItem key={s.id} value={String(s.id)}>{s.name}</SelectItem>
                ))}
              </SelectContent>
            </Select>
            <Select value={tagFilter} onValueChange={setTagFilter}>
              <SelectTrigger className="w-[140px]"><SelectValue placeholder="Tag" /></SelectTrigger>
              <SelectContent>
                <SelectItem value="all">All Tags</SelectItem>
                {(tags ?? []).map((t) => (
                  <SelectItem key={t.id} value={String(t.id)}>
                    <span className="flex items-center gap-2">
                      <span className="h-2 w-2 rounded-full inline-block" style={{ backgroundColor: t.color }} />
                      {t.name}
                    </span>
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <Select value={typeFilter} onValueChange={setTypeFilter}>
              <SelectTrigger className="w-[130px]"><SelectValue placeholder="Type" /></SelectTrigger>
              <SelectContent>
                <SelectItem value="all">All Types</SelectItem>
                <SelectItem value="pdf">PDF</SelectItem>
                <SelectItem value="video">Video</SelectItem>
                <SelectItem value="link">Link</SelectItem>
                <SelectItem value="document">Document</SelectItem>
                <SelectItem value="article">Article</SelectItem>
                <SelectItem value="audio">Audio</SelectItem>
                <SelectItem value="image">Image</SelectItem>
              </SelectContent>
            </Select>
          </div>
          <div className="flex items-center gap-3">
            <div className="flex items-center gap-2 text-sm text-muted-foreground">
              <CalendarDays className="h-4 w-4" />
              <span>From</span>
              <Input type="date" value={dateFrom} onChange={e => setDateFrom(e.target.value)} className="w-[150px] h-8 text-xs" />
              <span>To</span>
              <Input type="date" value={dateTo} onChange={e => setDateTo(e.target.value)} className="w-[150px] h-8 text-xs" />
            </div>
            {hasActiveFilters && (
              <Button variant="ghost" size="sm" onClick={clearFilters} className="text-muted-foreground">
                <X className="h-3 w-3 mr-1" /> Clear filters
              </Button>
            )}
          </div>
        </CardHeader>
        <CardContent>
          {isLoading ? (
            <div className="flex justify-center py-12"><Loader2 className="h-8 w-8 animate-spin text-muted-foreground" /></div>
          ) : (
            <Tabs value={activeTab} onValueChange={setActiveTab}>
              <TabsList className="mb-4">
                <TabsTrigger value="all">All ({resources.length + courseMaterials.length})</TabsTrigger>
                <TabsTrigger value="library">Shared Library ({resources.length})</TabsTrigger>
                <TabsTrigger value="materials">Course Materials ({courseMaterials.length})</TabsTrigger>
              </TabsList>

              <TabsContent value="all">
                <ResourceTable resources={resources} materials={courseMaterials} showSource onDelete={(id) => { if (window.confirm("Delete?")) deleteMutation.mutate(id); }} deletePending={deleteMutation.isPending} toast={toast} formatDate={formatDate} />
              </TabsContent>
              <TabsContent value="library">
                <ResourceTable resources={resources} materials={[]} onDelete={(id) => { if (window.confirm("Delete?")) deleteMutation.mutate(id); }} deletePending={deleteMutation.isPending} toast={toast} formatDate={formatDate} />
              </TabsContent>
              <TabsContent value="materials">
                <ResourceTable resources={[]} materials={courseMaterials} showCourseInfo onDelete={() => {}} deletePending={false} toast={toast} formatDate={formatDate} />
              </TabsContent>
            </Tabs>
          )}
        </CardContent>
      </Card>

      {/* Upload Dialog */}
      <Dialog open={showUpload} onOpenChange={(o) => { setShowUpload(o); if (!o) { setUploadTagIds([]); setUploadSubjectId("none"); setUploadDomainId("none"); setUploadTopicIds([]); setUploadObjectiveIds([]); } }}>
        <DialogContent className="sm:max-w-[540px] max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2"><Plus className="h-5 w-5" /> Upload New Resource</DialogTitle>
          </DialogHeader>
          <form onSubmit={handleUpload} className="space-y-4 pt-2">
            <input type="hidden" name="resource_type" value={uploadType} />
            {uploadSubjectId !== "none" && <input type="hidden" name="subject_id" value={uploadSubjectId} />}
            <div className="space-y-2"><Label>Name *</Label><Input name="name" placeholder="Resource title" required /></div>
            <div className="space-y-2">
              <Label>Type</Label>
              <Select value={uploadType} onValueChange={setUploadType}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="pdf">PDF</SelectItem>
                  <SelectItem value="video">Video</SelectItem>
                  <SelectItem value="document">Document</SelectItem>
                  <SelectItem value="link">Link / URL</SelectItem>
                  <SelectItem value="audio">Audio</SelectItem>
                  <SelectItem value="image">Image</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <TaxonomyCascade
              subjectId={uploadSubjectId} onSubjectChange={setUploadSubjectId}
              domainId={uploadDomainId} onDomainChange={setUploadDomainId}
              topicIds={uploadTopicIds} onTopicIdsChange={setUploadTopicIds}
              objectiveIds={uploadObjectiveIds} onObjectiveIdsChange={setUploadObjectiveIds}
            />
            <InlineTagPicker
              allTags={tags ?? []}
              selectedIds={uploadTagIds}
              onToggle={toggleUploadTag}
              onTagCreated={() => qc.invalidateQueries({ queryKey: ["resource-tags"] })}
            />
            <div className="space-y-2"><Label>File</Label><Input name="file" type="file" ref={fileRef} /></div>
            <DialogFooter>
              <Button type="button" variant="ghost" onClick={() => setShowUpload(false)}>Cancel</Button>
              <Button type="submit" disabled={uploadMutation.isPending}>
                {uploadMutation.isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
                Upload
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>
    </div>
  );
}

function ResourceTable({
  resources, materials, showSource, showCourseInfo, onDelete, deletePending, toast, formatDate,
}: {
  resources: Resource[];
  materials: CourseMaterialItem[];
  showSource?: boolean;
  showCourseInfo?: boolean;
  onDelete: (id: number) => void;
  deletePending: boolean;
  toast: ReturnType<typeof useToast>["toast"];
  formatDate: (iso?: string) => string;
}) {
  type Row = {
    key: string; name: string; type: string; source: "library" | "course";
    context: string; tags?: { id: number; name: string; color: string }[];
    status?: string; createdAt?: string; resourceId?: number;
  };

  const rows: Row[] = [
    ...resources.map((r): Row => ({
      key: `r-${r.id}`, name: r.name, type: r.resource_type, source: "library",
      context: [r.subject_name, ...(r.topic_names?.slice(0, 2) ?? [])].filter(Boolean).join(" › ") || "",
      tags: r.tags ?? [], status: r.review_status, createdAt: r.created_at, resourceId: r.id,
    })),
    ...materials.map((m): Row => ({
      key: `m-${m.id}`, name: m.name, type: m.type, source: "course",
      context: showCourseInfo || showSource ? `${m.course_name} › ${m.chapter_name}` : m.chapter_name || "",
    })),
  ];

  if (rows.length === 0) {
    return (
      <div className="text-center py-12 text-muted-foreground">
        <Library className="h-12 w-12 mx-auto mb-3 opacity-40" />
        <p className="font-medium">No resources found</p>
        <p className="text-sm">Upload a resource or add materials to your courses.</p>
      </div>
    );
  }

  return (
    <Table>
      <TableHeader>
        <TableRow>
          <TableHead>Name</TableHead>
          <TableHead>Type</TableHead>
          {showSource && <TableHead>Source</TableHead>}
          <TableHead>Subject / Tags</TableHead>
          <TableHead>Status</TableHead>
          <TableHead>Uploaded</TableHead>
          <TableHead className="text-right">Actions</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {rows.map((row) => {
          const sb = row.status ? (statusBadge[row.status] ?? statusBadge.pending) : null;
          return (
            <TableRow key={row.key}>
              <TableCell>
                <div className="flex items-center gap-2">
                  {typeIcons[row.type] ?? <FileText className="h-4 w-4" />}
                  <span className="font-medium">{row.name}</span>
                </div>
              </TableCell>
              <TableCell><Badge variant="outline" className="capitalize">{row.type}</Badge></TableCell>
              {showSource && (
                <TableCell>
                  <Badge variant={row.source === "library" ? "secondary" : "default"} className="text-xs">
                    {row.source === "library" ? "Library" : <><BookOpen className="h-3 w-3 mr-1 inline" />Course</>}
                  </Badge>
                </TableCell>
              )}
              <TableCell>
                <div className="flex flex-col gap-1">
                  {row.context && <span className="text-xs text-muted-foreground">{row.context}</span>}
                  {row.tags && row.tags.length > 0 && (
                    <div className="flex flex-wrap gap-1">
                      {row.tags.map((t) => (
                        <span key={t.id} className="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium text-white" style={{ backgroundColor: t.color }}>{t.name}</span>
                      ))}
                    </div>
                  )}
                  {!row.context && (!row.tags || row.tags.length === 0) && <span className="text-muted-foreground">—</span>}
                </div>
              </TableCell>
              <TableCell>
                {sb ? (
                  <Badge variant={sb.variant} className="flex items-center w-fit">{sb.icon}{row.status}</Badge>
                ) : (
                  <Badge variant="default" className="flex items-center w-fit"><CheckCircle2 className="h-3 w-3 mr-1" />indexed</Badge>
                )}
              </TableCell>
              <TableCell className="text-xs text-muted-foreground whitespace-nowrap">{formatDate(row.createdAt)}</TableCell>
              <TableCell className="text-right">
                <div className="flex items-center justify-end gap-1">
                  {row.source === "library" && row.resourceId && (
                    <>
                      <Button variant="ghost" size="icon" title="Download" onClick={async () => {
                        try {
                          const { blob, filename } = await resourcesService.download(row.resourceId!);
                          const url = URL.createObjectURL(blob); const a = document.createElement("a");
                          a.href = url; a.download = filename || row.name || "resource"; a.click(); URL.revokeObjectURL(url);
                        } catch { toast({ title: "Download failed", variant: "destructive" }); }
                      }}>
                        <Download className="h-4 w-4" />
                      </Button>
                      <Button variant="ghost" size="icon" title="Delete" onClick={() => onDelete(row.resourceId!)} disabled={deletePending}>
                        <Trash2 className="h-4 w-4 text-destructive" />
                      </Button>
                    </>
                  )}
                </div>
              </TableCell>
            </TableRow>
          );
        })}
      </TableBody>
    </Table>
  );
}

const INLINE_TAG_COLORS = ["#3b82f6", "#ef4444", "#22c55e", "#f59e0b", "#8b5cf6", "#ec4899", "#06b6d4"];

function InlineTagPicker({
  allTags, selectedIds, onToggle, onTagCreated,
}: {
  allTags: ResourceTag[];
  selectedIds: number[];
  onToggle: (id: number) => void;
  onTagCreated: (tag: ResourceTag) => void;
}) {
  const [newName, setNewName] = useState("");
  const [creating, setCreating] = useState(false);

  const handleCreate = async () => {
    const name = newName.trim();
    if (!name) return;
    setCreating(true);
    try {
      const color = INLINE_TAG_COLORS[Math.floor(Math.random() * INLINE_TAG_COLORS.length)];
      const tag = await resourcesService.createTag({ name, color });
      onTagCreated(tag);
      onToggle(tag.id);
      setNewName("");
    } catch { /* ignore */ }
    setCreating(false);
  };

  return (
    <div className="space-y-2">
      <Label>Tags</Label>
      <div className="flex flex-wrap gap-2">
        {allTags.map((t) => (
          <Badge
            key={t.id}
            variant={selectedIds.includes(t.id) ? "default" : "outline"}
            className="cursor-pointer select-none transition-colors"
            style={selectedIds.includes(t.id) ? { backgroundColor: t.color, borderColor: t.color, color: "#fff" } : { borderColor: t.color, color: t.color }}
            onClick={() => onToggle(t.id)}
          >
            {t.name}
          </Badge>
        ))}
      </div>
      <div className="flex gap-2 items-center">
        <Input
          placeholder="New tag…"
          value={newName}
          onChange={(e) => setNewName(e.target.value)}
          onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); handleCreate(); } }}
          className="h-8 text-sm flex-1"
        />
        <Button type="button" size="sm" variant="outline" disabled={!newName.trim() || creating} onClick={handleCreate}>
          {creating ? <Loader2 className="h-3 w-3 animate-spin" /> : <><Plus className="h-3 w-3 mr-1" />Add</>}
        </Button>
      </div>
    </div>
  );
}
