"use client";

import React, { useState, useEffect } from "react";
import { useSession } from "next-auth/react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
} from "@/components/ui/command";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button";
import { Loader2, Check, ChevronsUpDown } from "lucide-react";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import { 
  createRevisionAction, 
  fetchDocumentsByPackageId, 
  fetchStagesByDocumentId, 
  fetchRevisionsByStageParams,
  Document,
  IssueStage,
  Revision
} from "@/lib/vendor-document/service";

interface PublishDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  packageId: number;
  formCode: string;
  fileBlob?: Blob;
}

export const PublishDialog: React.FC<PublishDialogProps> = ({
  open,
  onOpenChange,
  packageId,
  formCode,
  fileBlob,
}) => {
  // Get current user session from next-auth
  const { data: session } = useSession();
  
  // State for form data
  const [documents, setDocuments] = useState<Document[]>([]);
  const [stages, setStages] = useState<IssueStage[]>([]);
  const [latestRevision, setLatestRevision] = useState<string>("");
  
  // State for document search
  const [openDocumentCombobox, setOpenDocumentCombobox] = useState(false);
  const [documentSearchValue, setDocumentSearchValue] = useState("");
  
  // Selected values
  const [selectedDocId, setSelectedDocId] = useState<string>("");
  const [selectedDocumentDisplay, setSelectedDocumentDisplay] = useState<string>("");
  const [selectedStage, setSelectedStage] = useState<string>("");
  const [revisionInput, setRevisionInput] = useState<string>("");
  const [uploaderName, setUploaderName] = useState<string>("");
  const [comment, setComment] = useState<string>("");
  const [customFileName, setCustomFileName] = useState<string>(`${formCode}_document.docx`);
  
  // Loading states
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
  
  // Filter documents by search
  const filteredDocuments = documentSearchValue
    ? documents.filter(doc => 
        doc.docNumber.toLowerCase().includes(documentSearchValue.toLowerCase()) ||
        doc.title.toLowerCase().includes(documentSearchValue.toLowerCase())
      )
    : documents;
  
  // Set uploader name from session when dialog opens
  useEffect(() => {
    if (open && session?.user?.name) {
      setUploaderName(session.user.name);
    }
  }, [open, session]);
  
  // Reset all fields when dialog opens/closes
  useEffect(() => {
    if (open) {
      setSelectedDocId("");
      setSelectedDocumentDisplay("");
      setSelectedStage("");
      setRevisionInput("");
      // Only set uploaderName if not already set from session
      if (!session?.user?.name) setUploaderName("");
      setComment("");
      setLatestRevision("");
      setCustomFileName(`${formCode}_document.docx`);
      setDocumentSearchValue("");
    }
  }, [open, formCode, session]);
  
  // Fetch documents based on packageId
  useEffect(() => {
    async function loadDocuments() {
      if (packageId && open) {
        setIsLoading(true);
        
        try {
          const docs = await fetchDocumentsByPackageId(packageId);
          setDocuments(docs);
        } catch (error) {
          console.error("Error fetching documents:", error);
          toast.error("Failed to load documents");
        } finally {
          setIsLoading(false);
        }
      }
    }
    
    loadDocuments();
  }, [packageId, open]);
  
  // Fetch stages when document is selected
  useEffect(() => {
    async function loadStages() {
      if (selectedDocId) {
        setIsLoading(true);
        
        // Reset dependent fields
        setSelectedStage("");
        setRevisionInput("");
        setLatestRevision("");
        
        try {
          const stagesList = await fetchStagesByDocumentId(parseInt(selectedDocId, 10));
          setStages(stagesList);
        } catch (error) {
          console.error("Error fetching stages:", error);
          toast.error("Failed to load stages");
        } finally {
          setIsLoading(false);
        }
      } else {
        setStages([]);
      }
    }
    
    loadStages();
  }, [selectedDocId]);
  
  // Fetch latest revision when stage is selected (for reference)
  useEffect(() => {
    async function loadLatestRevision() {
      if (selectedDocId && selectedStage) {
        setIsLoading(true);
        
        try {
          const revsList = await fetchRevisionsByStageParams(
            parseInt(selectedDocId, 10), 
            selectedStage
          );
          
          // Find the latest revision (assuming revisions are sorted by revision number)
          if (revsList.length > 0) {
            // Sort revisions if needed
            const sortedRevisions = [...revsList].sort((a, b) => {
              return b.revision.localeCompare(a.revision, undefined, { numeric: true });
            });
            
            setLatestRevision(sortedRevisions[0].revision);
            
            // Pre-fill the revision input with an incremented value if possible
            if (sortedRevisions[0].revision.match(/^\d+$/)) {
              // If it's a number, increment it
              const nextRevision = String(parseInt(sortedRevisions[0].revision, 10) + 1);
              setRevisionInput(nextRevision);
            } else if (sortedRevisions[0].revision.match(/^[A-Za-z]$/)) {
              // If it's a single letter, get the next letter
              const currentChar = sortedRevisions[0].revision.charCodeAt(0);
              const nextChar = String.fromCharCode(currentChar + 1);
              setRevisionInput(nextChar);
            } else {
              // For other formats, just show the latest as reference
              setRevisionInput("");
            }
          } else {
            // If no revisions exist, set default values
            setLatestRevision("");
            setRevisionInput("0");
          }
        } catch (error) {
          console.error("Error fetching revisions:", error);
          toast.error("Failed to load revision information");
        } finally {
          setIsLoading(false);
        }
      } else {
        setLatestRevision("");
        setRevisionInput("");
      }
    }
    
    loadLatestRevision();
  }, [selectedDocId, selectedStage]);
  
  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    
    if (!selectedDocId || !selectedStage || !revisionInput || !fileBlob) {
      toast.error("Please fill in all required fields");
      return;
    }
    
    setIsSubmitting(true);
    
    try {
      // Create FormData
      const formData = new FormData();
      formData.append("documentId", selectedDocId);
      formData.append("stage", selectedStage);
      formData.append("revision", revisionInput);
      formData.append("customFileName", customFileName);
      formData.append("uploaderType", "vendor"); // Default value
      
      if (uploaderName) {
        formData.append("uploaderName", uploaderName);
      }
      
      if (comment) {
        formData.append("comment", comment);
      }
      
      // Append file as attachment
      if (fileBlob) {
        const file = new File([fileBlob], customFileName, { 
          type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" 
        });
        formData.append("attachment", file);
      }
      
      // Call server action directly
      const result = await createRevisionAction(formData);
      
      if (result) {
        toast.success("Document published successfully!");
        onOpenChange(false);
      }
    } catch (error) {
      console.error("Error publishing document:", error);
      toast.error("Failed to publish document");
    } finally {
      setIsSubmitting(false);
    }
  };
  
  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[500px]">
        <DialogHeader>
          <DialogTitle>Publish Document</DialogTitle>
          <DialogDescription>
            Select document, stage, and revision to publish the vendor document.
          </DialogDescription>
        </DialogHeader>
        
        <form onSubmit={handleSubmit}>
          <div className="grid gap-4 py-4">
            {/* Document Selection with Search */}
            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="document" className="text-right">
                Document
              </Label>
              <div className="col-span-3">
                <Popover 
                  open={openDocumentCombobox} 
                  onOpenChange={setOpenDocumentCombobox}
                >
                  <PopoverTrigger asChild>
                    <Button
                      variant="outline"
                      role="combobox"
                      aria-expanded={openDocumentCombobox}
                      className="w-full justify-between"
                      disabled={isLoading || documents.length === 0}
                    >
                      {/* Add text-overflow handling for selected document display */}
                      <span className="truncate">
                        {selectedDocumentDisplay 
                          ? selectedDocumentDisplay 
                          : "Select document..."}
                      </span>
                      <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="w-[400px] p-0">
                    <Command>
                      <CommandInput 
                        placeholder="Search document..." 
                        value={documentSearchValue}
                        onValueChange={setDocumentSearchValue}
                      />
                      <CommandEmpty>No document found.</CommandEmpty>
                      <CommandGroup className="max-h-[300px] overflow-auto">
                        {filteredDocuments.map((doc) => (
                          <CommandItem
                            key={doc.id}
                            value={`${doc.docNumber} - ${doc.title}`}
                            onSelect={() => {
                              setSelectedDocId(String(doc.id));
                              setSelectedDocumentDisplay(`${doc.docNumber} - ${doc.title}`);
                              setOpenDocumentCombobox(false);
                            }}
                            className="flex items-center"
                          >
                            <Check
                              className={cn(
                                "mr-2 h-4 w-4 flex-shrink-0",
                                selectedDocId === String(doc.id) 
                                  ? "opacity-100" 
                                  : "opacity-0"
                              )}
                            />
                            {/* Add text-overflow handling for document items */}
                            <span className="truncate">{doc.docNumber} - {doc.title}</span>
                          </CommandItem>
                        ))}
                      </CommandGroup>
                    </Command>
                  </PopoverContent>
                </Popover>
              </div>
            </div>
            
            {/* Stage Selection */}
            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="stage" className="text-right">
                Stage
              </Label>
              <div className="col-span-3">
                <Select
                  value={selectedStage}
                  onValueChange={setSelectedStage}
                  disabled={isLoading || !selectedDocId || stages.length === 0}
                >
                  <SelectTrigger>
                    <SelectValue placeholder="Select stage" />
                  </SelectTrigger>
                  <SelectContent>
                    {stages.map((stage) => (
                      <SelectItem key={stage.id} value={stage.stageName}>
                        {/* Add text-overflow handling for stage names */}
                        <span className="truncate">{stage.stageName}</span>
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            </div>
            
            {/* Revision Input */}
            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="revision" className="text-right">
                Revision
              </Label>
              <div className="col-span-3">
                <Input
                  id="revision"
                  value={revisionInput}
                  onChange={(e) => setRevisionInput(e.target.value)}
                  placeholder="Enter revision"
                  disabled={isLoading || !selectedStage}
                />
                {latestRevision && (
                  <p className="text-xs text-muted-foreground mt-1">
                    Latest revision: {latestRevision}
                  </p>
                )}
              </div>
            </div>
            
            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="fileName" className="text-right">
                File Name
              </Label>
              <div className="col-span-3">
                <Input
                  id="fileName"
                  value={customFileName}
                  onChange={(e) => setCustomFileName(e.target.value)}
                  placeholder="Custom file name"
                />
              </div>
            </div>
            
            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="uploaderName" className="text-right">
                Uploader
              </Label>
              <div className="col-span-3">
                <Input
                  id="uploaderName"
                  value={uploaderName}
                  onChange={(e) => setUploaderName(e.target.value)}
                  placeholder="Your name"
                  // Disable input but show a filled style
                  className={session?.user?.name ? "opacity-70" : ""}
                  readOnly={!!session?.user?.name}
                />
                {session?.user?.name && (
                  <p className="text-xs text-muted-foreground mt-1">
                    Using your account name from login
                  </p>
                )}
              </div>
            </div>
            
            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="comment" className="text-right">
                Comment
              </Label>
              <div className="col-span-3">
                <Textarea
                  id="comment"
                  value={comment}
                  onChange={(e) => setComment(e.target.value)}
                  placeholder="Optional comment"
                  className="resize-none"
                />
              </div>
            </div>
          </div>
          
          <DialogFooter>
            <Button 
              type="submit" 
              disabled={isSubmitting || !selectedDocId || !selectedStage || !revisionInput}
            >
              {isSubmitting ? (
                <>
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  Publishing...
                </>
              ) : (
                "Publish"
              )}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
};