import { useState, useEffect, useMemo } from "react";
import { supabase } from "@/integrations/supabase/client";
import { useToast } from "@/hooks/use-toast";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog";
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 { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Loader2, Send, X, FileSignature, UserPlus, Upload, FolderOpen, FileText, ChevronLeft, ChevronRight } from "lucide-react";
import SignatureFieldPlacer, { PlacedField } from "@/components/SignatureFieldPlacer";

interface Recipient { name: string; email: string }

interface AvriaSignSendDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  documentUrl?: string;
  documentName?: string;
  associationId?: string;
  onSuccess?: () => void;
}

function arrayBufferToBase64(buffer: ArrayBuffer) {
  const bytes = new Uint8Array(buffer);
  const chunkSize = 0x8000;
  let binary = "";
  for (let i = 0; i < bytes.length; i += chunkSize) {
    binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));
  }
  return btoa(binary);
}

export default function AvriaSignSendDialog({
  open, onOpenChange, documentUrl, documentName: initialDocName, associationId: initialAssocId, onSuccess,
}: AvriaSignSendDialogProps) {
  const { toast } = useToast();
  const [step, setStep] = useState<1 | 2>(1);
  const [sending, setSending] = useState(false);
  const [associations, setAssociations] = useState<any[]>([]);
  const [associationId, setAssociationId] = useState(initialAssocId || "");
  const [documentName, setDocumentName] = useState(initialDocName || "");
  const [emailSubject, setEmailSubject] = useState("");
  const [emailBody, setEmailBody] = useState("");
  const [recipients, setRecipients] = useState<Recipient[]>([{ name: "", email: "" }]);
  const [file, setFile] = useState<File | null>(null);
  const [sourceMode, setSourceMode] = useState<"upload" | "library">("upload");
  const [libraryDocs, setLibraryDocs] = useState<any[]>([]);
  const [selectedDocUrl, setSelectedDocUrl] = useState<string>(documentUrl || "");
  const [fields, setFields] = useState<PlacedField[]>([]);

  // Local preview URL (created from File for the placer)
  const [localFileUrl, setLocalFileUrl] = useState<string>("");

  useEffect(() => {
    if (!open) return;
    setStep(1);
    setFields([]);
    supabase.from("associations").select("id, name").eq("status", "active").order("name")
      .then(({ data }) => setAssociations(data || []));
    if (initialAssocId) setAssociationId(initialAssocId);
    if (initialDocName) setDocumentName(initialDocName);
    if (documentUrl) { setSelectedDocUrl(documentUrl); setSourceMode("upload"); }
  }, [open, initialAssocId, initialDocName, documentUrl]);

  useEffect(() => {
    if (sourceMode === "library" && libraryDocs.length === 0) {
      supabase.from("documents" as any).select("id, title, file_url").order("created_at", { ascending: false }).limit(50)
        .then(({ data }) => setLibraryDocs((data as any[]) || []));
    }
  }, [sourceMode, libraryDocs.length]);

  // Build a preview URL when a file is chosen
  useEffect(() => {
    if (file) {
      const url = URL.createObjectURL(file);
      setLocalFileUrl(url);
      return () => URL.revokeObjectURL(url);
    }
    setLocalFileUrl("");
  }, [file]);

  const previewUrl = useMemo(() => {
    if (sourceMode === "upload" && localFileUrl) return localFileUrl;
    if (selectedDocUrl) return selectedDocUrl;
    return "";
  }, [sourceMode, localFileUrl, selectedDocUrl]);

  const validRecipients = recipients.filter(r => r.name.trim() && r.email.trim());

  const addRecipient = () => setRecipients([...recipients, { name: "", email: "" }]);
  const removeRecipient = (i: number) => recipients.length > 1 && setRecipients(recipients.filter((_, idx) => idx !== i));
  const updateRecipient = (i: number, k: keyof Recipient, v: string) => {
    const u = [...recipients]; u[i] = { ...u[i], [k]: v }; setRecipients(u);
  };

  const goToStep2 = () => {
    if (validRecipients.length === 0) {
      toast({ variant: "destructive", title: "Add at least one recipient" }); return;
    }
    if (sourceMode === "upload" && !file && !selectedDocUrl) {
      toast({ variant: "destructive", title: "Upload a document" }); return;
    }
    if (sourceMode === "library" && !selectedDocUrl) {
      toast({ variant: "destructive", title: "Select a document from the library" }); return;
    }
    setStep(2);
  };

  const handleSend = async () => {
    setSending(true);
    try {
      const payload: any = {
        association_id: associationId || null,
        document_name: documentName || file?.name || "Document",
        recipients: validRecipients,
        email_subject: emailSubject || `Please sign: ${documentName || "Document"}`,
        email_body: emailBody || undefined,
        // map field recipientIndex → recipient slot in same order as validRecipients
        fields: fields.map(f => ({
          recipient_index: f.recipientIndex,
          field_type: f.field_type,
          page_number: f.page_number,
          x_ratio: f.x_ratio,
          y_ratio: f.y_ratio,
          width_ratio: f.width_ratio,
          height_ratio: f.height_ratio,
        })),
      };

      if (sourceMode === "upload" && file) {
        payload.document_base64 = arrayBufferToBase64(await file.arrayBuffer());
        payload.file_extension = file.name.split(".").pop() || "pdf";
      } else if (selectedDocUrl) {
        payload.document_url = selectedDocUrl;
      }

      const { data, error } = await supabase.functions.invoke("avria-sign-send", { body: payload });
      if (error) throw error;
      if (data?.error) throw new Error(data.error);

      toast({ title: "Sent for Signature", description: `Envelope sent to ${validRecipients.length} recipient(s).` });
      onSuccess?.();
      onOpenChange(false);
      setRecipients([{ name: "", email: "" }]); setFile(null); setDocumentName("");
      setEmailSubject(""); setEmailBody(""); setSelectedDocUrl(""); setFields([]); setStep(1);
    } catch (err: any) {
      console.error("Avria Sign send error:", err);
      toast({ variant: "destructive", title: "Failed to Send", description: err.message || "Error sending document." });
    } finally {
      setSending(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-3xl max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <FileSignature className="h-5 w-5 text-primary" />
            {step === 1 ? "Send for Signature" : "Place Signature Fields"}
          </DialogTitle>
          <DialogDescription>
            {step === 1
              ? "Step 1 of 2 — Choose document & recipients."
              : "Step 2 of 2 — Click on the document to place where each signer should sign or date."}
          </DialogDescription>
        </DialogHeader>

        {step === 1 ? (
          <div className="space-y-4 py-2">
            <div className="space-y-1.5">
              <Label>Association (optional)</Label>
              <Select value={associationId} onValueChange={setAssociationId}>
                <SelectTrigger><SelectValue placeholder="Select association" /></SelectTrigger>
                <SelectContent>
                  {associations.map(a => <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>)}
                </SelectContent>
              </Select>
            </div>

            <div className="space-y-1.5">
              <Label>Document Source</Label>
              <Tabs value={sourceMode} onValueChange={(v) => setSourceMode(v as any)}>
                <TabsList className="grid grid-cols-2 w-full">
                  <TabsTrigger value="upload"><Upload className="h-3.5 w-3.5 mr-1" /> Upload</TabsTrigger>
                  <TabsTrigger value="library"><FolderOpen className="h-3.5 w-3.5 mr-1" /> Library</TabsTrigger>
                </TabsList>
                <TabsContent value="upload" className="pt-2">
                  <Input type="file" accept=".pdf" onChange={e => {
                    const f = e.target.files?.[0] || null; setFile(f); setSelectedDocUrl("");
                    if (f && !documentName) setDocumentName(f.name);
                  }} />
                </TabsContent>
                <TabsContent value="library" className="pt-2 max-h-48 overflow-y-auto border rounded-md">
                  {libraryDocs.length === 0 ? (
                    <p className="text-sm text-muted-foreground p-3">No documents in library.</p>
                  ) : libraryDocs.map(d => (
                    <button key={d.id} type="button" onClick={() => { setSelectedDocUrl(d.file_url); setDocumentName(d.title); setFile(null); }}
                      className={`w-full text-left p-2 text-sm hover:bg-muted ${selectedDocUrl === d.file_url ? "bg-muted" : ""}`}>
                      {d.title}
                    </button>
                  ))}
                </TabsContent>
              </Tabs>
            </div>

            <div className="space-y-1.5">
              <Label>Document Name</Label>
              <Input value={documentName} onChange={e => setDocumentName(e.target.value)} placeholder="e.g., Estoppel Certificate" />
            </div>

            <div className="grid grid-cols-1 gap-3">
              <div className="space-y-1.5">
                <Label>Email Subject (optional)</Label>
                <Input value={emailSubject} onChange={e => setEmailSubject(e.target.value)} placeholder={`Please sign: ${documentName || "Document"}`} />
              </div>
              <div className="space-y-1.5">
                <Label>Message (optional)</Label>
                <Textarea value={emailBody} onChange={e => setEmailBody(e.target.value)} rows={2} placeholder="Please review and sign." />
              </div>
            </div>

            <div className="space-y-2">
              <div className="flex items-center justify-between">
                <Label>Recipients</Label>
                <Button type="button" variant="ghost" size="sm" onClick={addRecipient} className="gap-1 h-7 text-xs">
                  <UserPlus className="h-3 w-3" /> Add Signer
                </Button>
              </div>
              {recipients.map((r, i) => (
                <div key={i} className="flex items-center gap-2">
                  <Input placeholder="Full name" value={r.name} onChange={e => updateRecipient(i, "name", e.target.value)} className="flex-1" />
                  <Input placeholder="Email" type="email" value={r.email} onChange={e => updateRecipient(i, "email", e.target.value)} className="flex-1" />
                  {recipients.length > 1 && (
                    <Button type="button" variant="ghost" size="icon" className="h-8 w-8 shrink-0" onClick={() => removeRecipient(i)}>
                      <X className="h-3.5 w-3.5" />
                    </Button>
                  )}
                </div>
              ))}
            </div>
          </div>
        ) : (
          <div className="py-2">
            {previewUrl ? (
              <SignatureFieldPlacer
                fileUrl={previewUrl}
                recipients={validRecipients}
                fields={fields}
                onChange={setFields}
              />
            ) : (
              <div className="border rounded p-6 text-sm text-muted-foreground text-center">
                Document preview unavailable. You can still send without placed fields — signers will use the bottom of the document.
              </div>
            )}
            <p className="text-xs text-muted-foreground mt-2">
              Tip: Click anywhere on the page. Fields are anchored to the document, not the screen.
              You can skip this step entirely and signers will sign at the bottom of the last page.
            </p>
          </div>
        )}

        <DialogFooter className="gap-2">
          {step === 2 && (
            <Button variant="outline" onClick={() => setStep(1)} disabled={sending} className="gap-1 mr-auto">
              <ChevronLeft className="h-4 w-4" /> Back
            </Button>
          )}
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={sending}>Cancel</Button>
          {step === 1 ? (
            <Button onClick={goToStep2} className="gap-1">
              Next: Place Fields <ChevronRight className="h-4 w-4" />
            </Button>
          ) : (
            <Button onClick={handleSend} disabled={sending} className="gap-2">
              {sending ? <Loader2 className="h-4 w-4 animate-spin" /> : <Send className="h-4 w-4" />}
              {sending ? "Sending..." : "Send for Signature"}
            </Button>
          )}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
