import { useState } from "react";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { useToast } from "@/hooks/use-toast";
import { useAuth } from "@/hooks/useAuth";
import { supabase } from "@/integrations/supabase/client";
import { useNavigate } from "react-router-dom";
import { Loader2, Upload, FileText, Youtube, Sparkles } from "lucide-react";
import { useDropzone } from "react-dropzone";
import { triggerIngest } from "@/lib/pipeline";
import { extractFileText } from "@/lib/extract";

const MAX_FILE_BYTES = 50 * 1024 * 1024; // 50MB
const AUDIO_EXTS = ["mp3", "wav", "m4a", "ogg", "flac", "webm"];
const VIDEO_EXTS = ["mp4", "mov", "mkv"];
const IMAGE_EXTS = ["png", "jpg", "jpeg", "webp", "bmp"];

export default function UploadDialog({ open, onOpenChange }: { open: boolean; onOpenChange: (v: boolean) => void }) {
  const { user } = useAuth();
  const { toast } = useToast();
  const navigate = useNavigate();
  const [submitting, setSubmitting] = useState(false);
  const [extractionProgress, setExtractionProgress] = useState(0);

  // Text mode
  const [textTitle, setTextTitle] = useState("");
  const [textContent, setTextContent] = useState("");
  // YouTube mode
  const [ytUrl, setYtUrl] = useState("");
  // File mode
  const [file, setFile] = useState<File | null>(null);

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    multiple: false,
    onDrop: (files) => setFile(files[0] ?? null),
  });

  const reset = () => {
    setTextTitle(""); setTextContent(""); setYtUrl(""); setFile(null);
    setExtractionProgress(0);
  };

  const createTextDoc = async () => {
    if (!user || !textContent.trim()) return;
    setSubmitting(true);
    try {
      // EXPERT OVERRIDE
      const EXPERT_PREFIX = `[EXPERT ADVISORY: ACT AS AN EXPERT ACADEMIC DATA EXTRACTION AGENT. 
STYLE: PROFESSIONAL, CLEAN MARKDOWN. NO EMOJIS ALLOWED.
DIRECTIVE: LOSSLESS EXTRACTION. ZERO OMISSION.
TEMPLATE: Overview -> Key Points -> Tables for Frameworks -> Sub-headings for Detailed Terms.]\n\n`;
      
      const finalContent = EXPERT_PREFIX + textContent;

      const { data, error } = await supabase
        .from("documents")
        .insert({
          user_id: user.id,
          title: textTitle.trim() || "Untitled note",
          source_type: "text",
          raw_text: finalContent,
          status: "ready",
        })
        .select("id")
        .single();
      if (error) throw error;
      toast({ title: "Document created", description: "Expert agent has saved your notes with lossless directives." });
      reset(); onOpenChange(false);
      navigate(`/app/doc/${data!.id}`);
    } catch (e: any) {
      toast({ title: "Failed", description: e.message, variant: "destructive" });
    } finally {
      setSubmitting(false);
    }
  };

  const createYoutubeDoc = async () => {
    if (!user || !ytUrl.trim()) return;
    setSubmitting(true);
    try {
      const { data, error } = await supabase
        .from("documents")
        .insert({
          user_id: user.id,
          title: ytUrl,
          source_type: "youtube",
          source_url: ytUrl,
          status: "pending",
        })
        .select("id")
        .single();
      if (error) throw error;
      toast({ title: "Source Queued", description: "Expert Agent is fetching the transcript..." });
      reset(); onOpenChange(false);
      navigate(`/app/doc/${data!.id}`);
      triggerIngest(data!.id).catch((e) =>
        toast({ title: "Extraction failed", description: e.message, variant: "destructive" }),
      );
    } catch (e: any) {
      toast({ title: "Failed", description: e.message, variant: "destructive" });
    } finally {
      setSubmitting(false);
    }
  };

  const createFileDoc = async () => {
    if (!user || !file) return;
    if (file.size > MAX_FILE_BYTES) {
      toast({ title: "File too large", description: "Expert Agent requires files under 50MB.", variant: "destructive" });
      return;
    }
    setSubmitting(true);
    try {
      const ext = file.name.split(".").pop()?.toLowerCase() ?? "";
      const isPdf = ext === "pdf";
      const isDocx = ext === "docx" || ext === "doc";
      const isImage = IMAGE_EXTS.includes(ext);
      const isAudio = AUDIO_EXTS.includes(ext);
      const isVideo = VIDEO_EXTS.includes(ext);

      // PDF/DOCX/Image: extract text in the browser, no file upload needed
      if (isPdf || isDocx || isImage) {
        toast({ title: "Expert Extraction Initialized", description: "Running parallel OCR and hierarchy mapping..." });
        const { text: extractedText, sourceType } = await extractFileText(file, (p) => setExtractionProgress(p));
        if (!extractedText || extractedText.trim().length < 5) {
          throw new Error("Expert Agent could not extract readable text from this file.");
        }

        // EXPERT OVERRIDE: Prepend instructions to ensure lossless extraction even if backend is old
        const EXPERT_PREFIX = `[EXPERT ADVISORY: ACT AS AN EXPERT ACADEMIC DATA EXTRACTION AGENT. 
STYLE: PROFESSIONAL, CLEAN MARKDOWN. NO EMOJIS ALLOWED.
DIRECTIVE: LOSSLESS EXTRACTION. ZERO OMISSION.
TEMPLATE: Overview -> Key Points -> Tables for Frameworks -> Sub-headings for Detailed Terms.]\n\n`;
        
        const finalRawText = EXPERT_PREFIX + extractedText;

        const { data, error } = await supabase
          .from("documents")
          .insert({
            user_id: user.id,
            title: file.name,
            source_type: sourceType,
            raw_text: finalRawText,
            status: "pending",
          })
          .select("id")
          .single();
        if (error) throw error;
        toast({ title: "Extraction Complete", description: "Expert Agent is finalizing the document..." });
        reset(); onOpenChange(false);
        navigate(`/app/doc/${data!.id}`);
        triggerIngest(data!.id).catch((e) =>
          toast({ title: "Ingest failed", description: e.message, variant: "destructive" }),
        );
        return;
      }

      // Audio/Video: upload to storage; ingest function transcribes via Groq Whisper
      if (!isAudio && !isVideo) {
        throw new Error("Unsupported file type. Use PDF, DOCX, Image, audio or video.");
      }
      const sourceType = isAudio ? "audio" : "video";
      const path = `${user.id}/${crypto.randomUUID()}-${file.name}`;
      const { error: upErr } = await supabase.storage.from("uploads").upload(path, file);
      if (upErr) throw upErr;

      const { data, error } = await supabase
        .from("documents")
        .insert({
          user_id: user.id,
          title: file.name,
          source_type: sourceType,
          source_url: path,
          status: "pending",
        })
        .select("id")
        .single();
      if (error) throw error;
      toast({ title: "Source Uploaded", description: "Expert Agent is initiating transcription..." });
      reset(); onOpenChange(false);
      navigate(`/app/doc/${data!.id}`);
      triggerIngest(data!.id).catch((e) =>
        toast({ title: "Ingest failed", description: e.message, variant: "destructive" }),
      );
    } catch (e: any) {
      toast({ title: "Failed", description: e.message, variant: "destructive" });
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-lg bg-slate-950 border-slate-800 text-white">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Sparkles className="h-5 w-5 text-primary" />
            Add Academic Source
          </DialogTitle>
        </DialogHeader>

        <Tabs defaultValue="file" className="w-full">
          <TabsList className="grid grid-cols-3 w-full bg-slate-900">
            <TabsTrigger value="file" className="data-[state=active]:bg-slate-800 text-xs">
              <Upload className="h-3.5 w-3.5 mr-1.5" /> File
            </TabsTrigger>
            <TabsTrigger value="youtube" className="data-[state=active]:bg-slate-800 text-xs">
              <Youtube className="h-3.5 w-3.5 mr-1.5" /> YouTube
            </TabsTrigger>
            <TabsTrigger value="text" className="data-[state=active]:bg-slate-800 text-xs">
              <FileText className="h-3.5 w-3.5 mr-1.5" /> Text
            </TabsTrigger>
          </TabsList>

          <TabsContent value="file" className="space-y-4 pt-4">
            <div
              {...getRootProps()}
              className={`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-all duration-300 ${
                isDragActive ? "border-primary bg-primary/10" : "border-slate-800 hover:border-primary/50 hover:bg-slate-900/50"
              }`}
            >
              <input {...getInputProps()} />
              <Upload className="h-8 w-8 mx-auto mb-3 text-slate-500" />
              {file ? (
                <p className="text-sm font-medium">{file.name}</p>
              ) : (
                <div className="space-y-1">
                  <p className="text-sm text-slate-300">
                    {isDragActive ? "Drop here…" : "Drag your academic document here"}
                  </p>
                  <p className="text-[11px] text-slate-500 uppercase tracking-tighter">
                    PDF, DOCX, Images, MP3, MP4 Supported
                  </p>
                </div>
              )}
            </div>

            {submitting && extractionProgress > 0 && (
              <div className="space-y-2">
                <div className="flex justify-between text-[10px] uppercase tracking-widest text-slate-500 font-bold">
                  <span>Extraction Progress</span>
                  <span>{extractionProgress}%</span>
                </div>
                <div className="h-1.5 w-full bg-slate-900 rounded-full overflow-hidden">
                  <div 
                    className="h-full bg-primary transition-all duration-300"
                    style={{ width: `${extractionProgress}%` }}
                  />
                </div>
              </div>
            )}

            <Button 
              onClick={createFileDoc} 
              disabled={!file || submitting} 
              className="w-full bg-primary hover:bg-primary/90 text-white font-semibold"
            >
              {submitting ? (
                <>
                  <Loader2 className="h-4 w-4 mr-2 animate-spin" />
                  {extractionProgress > 0 ? "Expert Scanning..." : "Processing..."}
                </>
              ) : (
                "Initialize Extraction"
              )}
            </Button>
          </TabsContent>

          <TabsContent value="youtube" className="space-y-4 pt-4">
            <div className="space-y-1.5">
              <Label htmlFor="yt" className="text-xs text-slate-400">YouTube URL</Label>
              <Input 
                id="yt" 
                value={ytUrl} 
                onChange={(e) => setYtUrl(e.target.value)} 
                placeholder="https://youtube.com/watch?v=..." 
                className="bg-slate-900 border-slate-800 text-white placeholder:text-slate-600"
              />
            </div>
            <Button onClick={createYoutubeDoc} disabled={!ytUrl.trim() || submitting} className="w-full bg-primary hover:bg-primary/90">
              {submitting && <Loader2 className="h-4 w-4 mr-2 animate-spin" />} Analyze Link
            </Button>
          </TabsContent>

          <TabsContent value="text" className="space-y-4 pt-4">
            <div className="space-y-1.5">
              <Label htmlFor="title" className="text-xs text-slate-400">Note Title</Label>
              <Input 
                id="title" 
                value={textTitle} 
                onChange={(e) => setTextTitle(e.target.value)} 
                placeholder="Untitled Lecture Notes" 
                className="bg-slate-900 border-slate-800 text-white placeholder:text-slate-600"
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="content" className="text-xs text-slate-400">Content</Label>
              <Textarea 
                id="content" 
                value={textContent} 
                onChange={(e) => setTextContent(e.target.value)} 
                rows={8} 
                placeholder="Paste your text here…" 
                className="bg-slate-900 border-slate-800 text-white placeholder:text-slate-600 resize-none"
              />
            </div>
            <Button onClick={createTextDoc} disabled={!textContent.trim() || submitting} className="w-full bg-primary hover:bg-primary/90">
              {submitting && <Loader2 className="h-4 w-4 mr-2 animate-spin" />} Create Expert Note
            </Button>
          </TabsContent>
        </Tabs>
      </DialogContent>
    </Dialog>
  );
}
