"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 { 
  createSubmissionAction, // 새로운 액션 이름
  fetchDocumentsByProjectAndPackage, // 업데이트된 액션
  fetchStagesByDocumentIdPlant, 
  fetchSubmissionsByStageParams, // revisions 대신 submissions
} from "@/lib/vendor-document/service";
import type { 
  StageDocument,
  StageIssueStage,
} from "@/db/schema/vendorDocu";

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

export const PublishDialog: React.FC<PublishDialogProps> = ({
  open,
  onOpenChange,
  projectCode,
  packageCode,
  formCode,
  fileBlob,
}) => {
  // Get current user session from next-auth
  const { data: session } = useSession();
  
  // State for form data
  const [documents, setDocuments] = useState<StageDocument[]>([]);
  const [stages, setStages] = useState<StageIssueStage[]>([]);
  const [latestRevisionCode, setLatestRevisionCode] = useState<string>("");
  const [latestRevisionNumber, setLatestRevisionNumber] = useState<number>(0);
  
  // 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 [revisionCodeInput, setRevisionCodeInput] = useState<string>("");
  const [submitterName, setSubmitterName] = useState<string>("");
  const [submissionTitle, setSubmissionTitle] = useState<string>("");
  const [submissionDescription, setSubmissionDescription] = 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 submitter name from session when dialog opens
  useEffect(() => {
    if (open && session?.user?.name) {
      setSubmitterName(session.user.name);
    }
  }, [open, session]);
  
  // Reset all fields when dialog opens/closes
  useEffect(() => {
    if (open) {
      setSelectedDocId("");
      setSelectedDocumentDisplay("");
      setSelectedStage("");
      setRevisionCodeInput("");
      setSubmissionTitle("");
      setSubmissionDescription("");
      // Only set submitterName if not already set from session
      if (!session?.user?.name) setSubmitterName("");
      setLatestRevisionCode("");
      setLatestRevisionNumber(0);
      setCustomFileName(`${formCode}_document.docx`);
      setDocumentSearchValue("");
    }
  }, [open, formCode, session]);
  
  // Fetch documents based on projectCode and packageCode
  useEffect(() => {
    async function loadDocuments() {
      if (projectCode && packageCode && open) {
        setIsLoading(true);
        
        try {
          const docs = await fetchDocumentsByProjectAndPackage(projectCode, packageCode);
          setDocuments(docs);
        } catch (error) {
          console.error("Error fetching documents:", error);
          toast.error("Failed to load documents");
        } finally {
          setIsLoading(false);
        }
      }
    }
    
    loadDocuments();
  }, [projectCode, packageCode, open]);
  
  // Fetch stages when document is selected
  useEffect(() => {
    async function loadStages() {
      if (selectedDocId) {
        setIsLoading(true);
        
        // Reset dependent fields
        setSelectedStage("");
        setRevisionCodeInput("");
        setLatestRevisionCode("");
        setLatestRevisionNumber(0);
        
        try {
          const stagesList = await fetchStagesByDocumentIdPlant(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 submission (revision) when stage is selected
  useEffect(() => {
    async function loadLatestSubmission() {
      if (selectedDocId && selectedStage) {
        setIsLoading(true);
        
        try {
          const submissionsList = await fetchSubmissionsByStageParams(
            parseInt(selectedDocId, 10), 
            selectedStage
          );
          
          // Find the latest submission (assuming sorted by revision number)
          if (submissionsList.length > 0) {
            // Sort submissions by revision number descending
            const sortedSubmissions = [...submissionsList].sort((a, b) => 
              b.revisionNumber - a.revisionNumber
            );
            
            const latestSubmission = sortedSubmissions[0];
            setLatestRevisionCode(latestSubmission.revisionCode);
            setLatestRevisionNumber(latestSubmission.revisionNumber);
            
            // Auto-increment revision code
            if (latestSubmission.revisionCode.match(/^\d+$/)) {
              // If it's a number, increment it
              const nextRevision = String(parseInt(latestSubmission.revisionCode, 10) + 1);
              setRevisionCodeInput(nextRevision);
            } else if (latestSubmission.revisionCode.match(/^[A-Za-z]$/)) {
              // If it's a single letter, get the next letter
              const currentChar = latestSubmission.revisionCode.charCodeAt(0);
              const nextChar = String.fromCharCode(currentChar + 1);
              setRevisionCodeInput(nextChar);
            } else if (latestSubmission.revisionCode.toLowerCase().startsWith("rev")) {
              // Handle "Rev0", "Rev1" format
              const numMatch = latestSubmission.revisionCode.match(/\d+$/);
              if (numMatch) {
                const nextNum = parseInt(numMatch[0], 10) + 1;
                setRevisionCodeInput(`Rev${nextNum}`);
              } else {
                setRevisionCodeInput("");
              }
            } else {
              // For other formats, just show the latest as reference
              setRevisionCodeInput("");
            }
          } else {
            // If no submissions exist, set default values
            setLatestRevisionCode("");
            setLatestRevisionNumber(0);
            setRevisionCodeInput("Rev0"); // Start with Rev0
          }
        } catch (error) {
          console.error("Error fetching submissions:", error);
          toast.error("Failed to load submission information");
        } finally {
          setIsLoading(false);
        }
      } else {
        setLatestRevisionCode("");
        setLatestRevisionNumber(0);
        setRevisionCodeInput("");
      }
    }
    
    loadLatestSubmission();
  }, [selectedDocId, selectedStage]);
  
  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    
    if (!selectedDocId || !selectedStage || !revisionCodeInput || !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("stageName", selectedStage);
      formData.append("revisionCode", revisionCodeInput);
      formData.append("customFileName", customFileName);
      
      if (submitterName) {
        formData.append("submittedBy", submitterName);
      }
      
      if (session?.user?.email) {
        formData.append("submittedByEmail", session.user.email);
      }
      
      if (submissionTitle) {
        formData.append("submissionTitle", submissionTitle);
      }
      
      if (submissionDescription) {
        formData.append("submissionDescription", submissionDescription);
      }
      
      // Get vendor info from selected document
      const selectedDoc = documents.find(doc => doc.id === parseInt(selectedDocId, 10));
      if (selectedDoc) {
        formData.append("vendorId", String(selectedDoc.vendorId));
      }
      
      // 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
      const result = await createSubmissionAction(formData);
      
      if (result.success) {
        toast.success("Document published successfully!");
        onOpenChange(false);
      } else {
        toast.error(result.error || "Failed to publish document");
      }
    } 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}
                    >
                      <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"
                              )}
                            />
                            <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}>
                        <span className="truncate">{stage.stageName}</span>
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            </div>
            
            {/* Revision Code Input */}
            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="revisionCode" className="text-right">
                Revision
              </Label>
              <div className="col-span-3">
                <Input
                  id="revisionCode"
                  value={revisionCodeInput}
                  onChange={(e) => setRevisionCodeInput(e.target.value)}
                  placeholder="Enter revision code (e.g., Rev0, A, 1)"
                  disabled={isLoading || !selectedStage}
                />
                {latestRevisionCode && (
                  <p className="text-xs text-muted-foreground mt-1">
                    Latest revision: {latestRevisionCode} (#{latestRevisionNumber})
                  </p>
                )}
              </div>
            </div>
            
            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="submissionTitle" className="text-right">
                Title
              </Label>
              <div className="col-span-3">
                <Input
                  id="submissionTitle"
                  value={submissionTitle}
                  onChange={(e) => setSubmissionTitle(e.target.value)}
                  placeholder="Optional submission title"
                />
              </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="submitterName" className="text-right">
                Submitter
              </Label>
              <div className="col-span-3">
                <Input
                  id="submitterName"
                  value={submitterName}
                  onChange={(e) => setSubmitterName(e.target.value)}
                  placeholder="Your name"
                  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="description" className="text-right">
                Description
              </Label>
              <div className="col-span-3">
                <Textarea
                  id="description"
                  value={submissionDescription}
                  onChange={(e) => setSubmissionDescription(e.target.value)}
                  placeholder="Optional submission description"
                  className="resize-none"
                />
              </div>
            </div>
          </div>
          
          <DialogFooter>
            <Button 
              type="submit" 
              disabled={isSubmitting || !selectedDocId || !selectedStage || !revisionCodeInput}
            >
              {isSubmitting ? (
                <>
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  Publishing...
                </>
              ) : (
                "Publish"
              )}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
};