import { useState, useEffect } from "react";
import { useSearchParams } from "react-router-dom";
import { Send, Paperclip, Eye, FileText, Loader2, Users, Mail } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Badge } from "@/components/ui/badge";
import { useToast } from "@/hooks/use-toast";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/contexts/AuthContext";
import { useAssociation } from "@/contexts/AssociationContext";
import { useFileUpload } from "@/hooks/useFileUpload";
import { sendEmailViaSMTP } from "@/lib/sendEmailViaSMTP";
import RichEmailEditor from "@/components/email/RichEmailEditor";
import OwnerEmailPicker from "@/components/email/OwnerEmailPicker";
import EmailSignatureManager, { EmailSignature } from "@/components/email/EmailSignatureManager";
import { Settings } from "lucide-react";

export default function ComposeEmailPage() {
  const { user } = useAuth();
  const { toast } = useToast();
  const [searchParams] = useSearchParams();
  const associationCtx = useAssociation() as any;
  const selectedAssociation = associationCtx?.selectedAssociation ?? null;
  const { uploadFiles, uploading } = useFileUpload();
  const [senders, setSenders] = useState<any[]>([]);
  const [templates, setTemplates] = useState<any[]>([]);
  const [senderId, setSenderId] = useState("");
  const [recipients, setRecipients] = useState("");
  const [cc, setCc] = useState("");
  const [bcc, setBcc] = useState("");
  const [showCc, setShowCc] = useState(false);
  const [showBcc, setShowBcc] = useState(false);
  const [templateId, setTemplateId] = useState("none");
  const [subject, setSubject] = useState("");
  const [content, setContent] = useState("");
  const [attachments, setAttachments] = useState<File[]>([]);
  const [sending, setSending] = useState(false);
  const [tab, setTab] = useState("content");
  const [pickerOpen, setPickerOpen] = useState<null | "to" | "cc" | "bcc">(null);
  const [sendMethod, setSendMethod] = useState<"smtp" | "mailchimp">("smtp");
  const [mailchimpConfig, setMailchimpConfig] = useState<any>(null);
  const [mcFromName, setMcFromName] = useState("");
  const [mcReplyTo, setMcReplyTo] = useState("");
  const [signatures, setSignatures] = useState<EmailSignature[]>([]);
  const [signatureId, setSignatureId] = useState<string>("none");
  const [signatureHtml, setSignatureHtml] = useState<string>("");
  const [signatureManagerOpen, setSignatureManagerOpen] = useState(false);

  const mergeEmails = (current: string, emails: string[]) => {
    const existing = current
      .split(",")
      .map((e) => e.trim().toLowerCase())
      .filter(Boolean);
    return Array.from(new Set([...existing, ...emails.map((e) => e.toLowerCase())])).join(", ");
  };

  const handlePickerConfirm = (emails: string[]) => {
    if (pickerOpen === "to") setRecipients((r) => mergeEmails(r, emails));
    else if (pickerOpen === "cc") {
      setCc((r) => mergeEmails(r, emails));
      setShowCc(true);
    } else if (pickerOpen === "bcc") {
      setBcc((r) => mergeEmails(r, emails));
      setShowBcc(true);
    }
  };

  const parseList = (raw: string) =>
    raw.split(",").map((e) => e.trim()).filter(Boolean);

  useEffect(() => {
    if (user) {
      fetchSenders();
      fetchTemplates();
      fetchSignatures();
    }
  }, [user]);

  useEffect(() => {
    const email = searchParams.get("email");
    const name = searchParams.get("name");
    if (email) setRecipients(email);
    if (name) setSubject(`Message for ${name}`);
  }, [searchParams]);

  useEffect(() => {
    const fetchMc = async () => {
      if (!selectedAssociation?.id) { setMailchimpConfig(null); return; }
      const { data } = await supabase
        .from("mailchimp_configs")
        .select("*")
        .eq("association_id", selectedAssociation.id)
        .maybeSingle();
      setMailchimpConfig(data || null);
      if (data) {
        setMcFromName((prev) => prev || selectedAssociation?.name || "");
        setMcReplyTo((prev) => prev || user?.email || "");
      }
    };
    fetchMc();
  }, [selectedAssociation?.id, user?.email]);

  const fetchSenders = async () => {
    const { data: result } = await supabase.functions.invoke("send-smtp-email", {
      body: { action: "list_senders" },
    });

    console.log("[ComposeEmail] Raw senders result:", JSON.stringify(result));
    // Handle both direct object and string response
    const parsed = typeof result === "string" ? JSON.parse(result) : result;
    const available = parsed?.senders || [];
    setSenders(available);
    if (available.length > 0) setSenderId(available[0].id);
  };

  const fetchTemplates = async () => {
    const { data } = await supabase.from("email_templates").select("id, name, subject, body_html").order("name");
    setTemplates(data || []);
  };

  const fetchSignatures = async () => {
    if (!user?.id) return;
    const { data } = await supabase
      .from("email_signatures" as any)
      .select("*")
      .eq("user_id", user.id)
      .order("is_default", { ascending: false })
      .order("name");
    const rows = (data || []) as unknown as EmailSignature[];
    setSignatures(rows);
    // Auto-apply default signature if user hasn't picked one yet
    const def = rows.find((s) => s.is_default);
    if (def && signatureId === "none") {
      setSignatureId(def.id);
      setSignatureHtml(def.html || "");
    }
  };

  const handleSignatureChange = (val: string) => {
    setSignatureId(val);
    if (val === "none") { setSignatureHtml(""); return; }
    const sig = signatures.find((s) => s.id === val);
    setSignatureHtml(sig?.html || "");
  };

  const composeBodyWithSignature = (body: string) =>
    signatureHtml ? `${body}<br/><br/>${signatureHtml}` : body;

  const handleTemplateChange = (val: string) => {
    setTemplateId(val);
    if (val !== "none") {
      const tmpl = templates.find((t: any) => t.id === val);
      if (tmpl) {
        setSubject(tmpl.subject || "");
        setContent(tmpl.body_html || "");
      }
    }
  };

  const detectVariables = () => {
    const matches = content.match(/\{\{(\w+)\}\}/g);
    return matches ? [...new Set(matches)] : [];
  };

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) setAttachments(Array.from(e.target.files));
  };

  const handleSendMailchimp = async (sendNow: boolean) => {
    if (!selectedAssociation?.id) {
      toast({ variant: "destructive", title: "No association", description: "Select an association first." });
      return;
    }
    if (!mailchimpConfig?.audience_id) {
      toast({ variant: "destructive", title: "Mailchimp not configured", description: "Set up Mailchimp + audience under Mailchimp settings." });
      return;
    }
    if (!subject.trim() || !content.trim() || !mcFromName.trim() || !mcReplyTo.trim()) {
      toast({ variant: "destructive", title: "Missing fields", description: "Subject, content, From name, and Reply-to are required." });
      return;
    }
    setSending(true);
    try {
      const { data, error } = await supabase.functions.invoke("mailchimp-campaign", {
        body: {
          association_id: selectedAssociation.id,
          subject,
          from_name: mcFromName,
          reply_to: mcReplyTo,
          html: composeBodyWithSignature(content),
          send_now: sendNow,
        },
      });
      if (error) throw error;
      if (!data?.success) throw new Error(data?.error || "Mailchimp send failed");
      toast({
        title: sendNow ? "Campaign Sent" : "Draft Saved",
        description: sendNow
          ? `Sent to your Mailchimp audience.`
          : `Draft saved in Mailchimp (campaign ${data.campaign_id}).`,
      });
      if (sendNow) {
        setSubject(""); setContent(""); setTemplateId("none");
      }
    } catch (err: any) {
      toast({ variant: "destructive", title: "Mailchimp Error", description: err.message });
    } finally {
      setSending(false);
    }
  };

  const handleSend = async () => {
    if (sendMethod === "mailchimp") {
      return handleSendMailchimp(true);
    }
    if (!senderId || !recipients.trim() || !subject.trim()) {
      toast({ variant: "destructive", title: "Validation Error", description: "Sender, recipients, and subject are required." });
      return;
    }

    const recipientList = parseList(recipients);
    const ccList = parseList(cc);
    const bccList = parseList(bcc);

    if (recipientList.length === 0) {
      toast({ variant: "destructive", title: "Validation Error", description: "Enter at least one valid recipient email." });
      return;
    }

    setSending(true);
    try {
      const uploadedAttachments = attachments.length > 0
        ? await uploadFiles(attachments, "files", "email-attachments")
        : [];

      // Chunk recipients to avoid SMTP connection timeouts on large blasts.
      // Each batch is a separate edge function invocation with a fresh SMTP connection.
      const BATCH_SIZE = 25;
      const batches: string[][] = [];
      for (let i = 0; i < recipientList.length; i += BATCH_SIZE) {
        batches.push(recipientList.slice(i, i + BATCH_SIZE));
      }

      let successCount = 0;
      let failedRecipients: string[] = [];
      const totalBatches = batches.length;

      for (let i = 0; i < batches.length; i++) {
        const batch = batches[i];
        // Only attach cc/bcc to the first batch to avoid duplicating them.
        const batchCc = i === 0 ? ccList : [];
        const batchBcc = i === 0 ? bccList : [];

        if (totalBatches > 1) {
          toast({
            title: `Sending batch ${i + 1} of ${totalBatches}`,
            description: `Processing ${batch.length} recipients...`,
          });
        }

        try {
          const result = await sendEmailViaSMTP({
            sender_id: senderId,
            recipient_email: batch,
            cc: batchCc,
            bcc: batchBcc,
            subject,
            htmlBody: composeBodyWithSignature(content),
            attachments: uploadedAttachments,
            debug: false,
          });

          if (result.success) {
            successCount += batch.length;
          } else {
            failedRecipients.push(...batch);
            console.error(`Batch ${i + 1} failed:`, result.error);
          }
        } catch (batchErr: any) {
          failedRecipients.push(...batch);
          console.error(`Batch ${i + 1} threw:`, batchErr);
        }

        // Brief pause between batches to be gentle with the SMTP server.
        if (i < batches.length - 1) {
          await new Promise(r => setTimeout(r, 1500));
        }
      }

      if (failedRecipients.length > 0 && successCount === 0) {
        throw new Error(`All ${failedRecipients.length} emails failed to send.`);
      }

      const totalCount = successCount + ccList.length + bccList.length;
      toast({
        title: failedRecipients.length > 0 ? "Partial Delivery" : "Email Sent",
        description: failedRecipients.length > 0
          ? `Sent to ${totalCount} recipients. ${failedRecipients.length} failed.`
          : `Delivered to ${totalCount} recipient${totalCount > 1 ? "s" : ""}.`,
        variant: failedRecipients.length > 0 ? "destructive" : "default",
      });
      setRecipients("");
      setCc("");
      setBcc("");
      setShowCc(false);
      setShowBcc(false);
      setSubject("");
      setContent("");
      setAttachments([]);
      setTemplateId("none");
    } catch (err: any) {
      toast({ variant: "destructive", title: "Send Failed", description: err.message });
    } finally {
      setSending(false);
    }
  };

  const variables = detectVariables();

  return (
    <div className="space-y-6">
      <div className="flex items-center gap-3">
        <Send className="h-7 w-7 text-primary" />
        <h1 className="text-2xl font-bold text-foreground">Compose Email</h1>
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
        <div className="lg:col-span-2 space-y-6">
          <Card>
            <CardHeader><CardTitle>Send Method</CardTitle></CardHeader>
            <CardContent className="space-y-2">
              <Select value={sendMethod} onValueChange={(v) => setSendMethod(v as "smtp" | "mailchimp")}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="smtp">SMTP (direct)</SelectItem>
                  <SelectItem value="mailchimp" disabled={!mailchimpConfig?.audience_id}>
                    Mailchimp Campaign {mailchimpConfig?.audience_id ? "" : "(not configured)"}
                  </SelectItem>
                </SelectContent>
              </Select>
              {sendMethod === "mailchimp" && !mailchimpConfig?.audience_id && (
                <p className="text-xs text-muted-foreground">
                  Configure Mailchimp and select an audience under the Mailchimp page first.
                </p>
              )}
              {sendMethod === "mailchimp" && mailchimpConfig?.audience_id && (
                <p className="text-xs text-muted-foreground">
                  Will send to your Mailchimp audience for <strong>{selectedAssociation?.name}</strong>. To/Cc/Bcc and SMTP sender are ignored.
                </p>
              )}
            </CardContent>
          </Card>

          <Card>
            <CardHeader><CardTitle>{sendMethod === "mailchimp" ? "Campaign Details" : "Sender & Recipients"}</CardTitle></CardHeader>
            <CardContent className="space-y-4">
              {sendMethod === "smtp" ? (
                <div className="space-y-2">
                  <Label>From <span className="text-destructive">*</span></Label>
                  <Select value={senderId} onValueChange={setSenderId}>
                    <SelectTrigger><SelectValue placeholder="Select Sender" /></SelectTrigger>
                    <SelectContent>
                      {senders.map((s: any) => (
                        <SelectItem key={s.id} value={s.id}>{s.sender_name} ({s.email_address})</SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              ) : (
                <>
                  <div className="space-y-2">
                    <Label>From Name <span className="text-destructive">*</span></Label>
                    <Input value={mcFromName} onChange={(e) => setMcFromName(e.target.value)} placeholder="Association Name" />
                  </div>
                  <div className="space-y-2">
                    <Label>Reply-to Email <span className="text-destructive">*</span></Label>
                    <Input type="email" value={mcReplyTo} onChange={(e) => setMcReplyTo(e.target.value)} placeholder="reply@example.com" />
                  </div>
                </>
              )}
              {sendMethod === "smtp" && (
                <>
                  <div className="space-y-2">
                    <div className="flex items-center justify-between flex-wrap gap-2">
                      <Label>To (comma separated) <span className="text-destructive">*</span></Label>
                      <div className="flex items-center gap-2">
                        {!showCc && (
                          <Button type="button" size="sm" variant="ghost" onClick={() => setShowCc(true)}>
                            Add Cc
                          </Button>
                        )}
                        {!showBcc && (
                          <Button type="button" size="sm" variant="ghost" onClick={() => setShowBcc(true)}>
                            Add Bcc
                          </Button>
                        )}
                        <Button type="button" size="sm" variant="outline" onClick={() => setPickerOpen("to")}>
                          <Users className="h-4 w-4 mr-2" /> Pick Homeowners
                        </Button>
                      </div>
                    </div>
                    <Input placeholder="client@example.com, owner@example.com" value={recipients} onChange={(e) => setRecipients(e.target.value)} />
                  </div>

                  {showCc && (
                    <div className="space-y-2">
                      <div className="flex items-center justify-between flex-wrap gap-2">
                        <Label>Cc</Label>
                        <div className="flex items-center gap-2">
                          <Button type="button" size="sm" variant="outline" onClick={() => setPickerOpen("cc")}>
                            <Users className="h-4 w-4 mr-2" /> Pick Homeowners
                          </Button>
                          <Button type="button" size="sm" variant="ghost" onClick={() => { setShowCc(false); setCc(""); }}>
                            Remove
                          </Button>
                        </div>
                      </div>
                      <Input placeholder="cc1@example.com, cc2@example.com" value={cc} onChange={(e) => setCc(e.target.value)} />
                    </div>
                  )}

                  {showBcc && (
                    <div className="space-y-2">
                      <div className="flex items-center justify-between flex-wrap gap-2">
                        <Label>Bcc</Label>
                        <div className="flex items-center gap-2">
                          <Button type="button" size="sm" variant="outline" onClick={() => setPickerOpen("bcc")}>
                            <Users className="h-4 w-4 mr-2" /> Pick Homeowners
                          </Button>
                          <Button type="button" size="sm" variant="ghost" onClick={() => { setShowBcc(false); setBcc(""); }}>
                            Remove
                          </Button>
                        </div>
                      </div>
                      <Input placeholder="bcc1@example.com, bcc2@example.com" value={bcc} onChange={(e) => setBcc(e.target.value)} />
                      <p className="text-xs text-muted-foreground">Bcc recipients are hidden from other recipients.</p>
                    </div>
                  )}
                </>
              )}
              <div className="space-y-2">
                <Label>Template</Label>
                <Select value={templateId} onValueChange={handleTemplateChange}>
                  <SelectTrigger><SelectValue placeholder="No Template (Custom)" /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value="none">No Template (Custom)</SelectItem>
                    {templates.map((t: any) => (
                      <SelectItem key={t.id} value={t.id}>{t.name}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-2">
                <div className="flex items-center justify-between">
                  <Label>Signature</Label>
                  <Button type="button" size="sm" variant="ghost" onClick={() => setSignatureManagerOpen(true)}>
                    <Settings className="h-4 w-4 mr-1" /> Manage
                  </Button>
                </div>
                <Select value={signatureId} onValueChange={handleSignatureChange}>
                  <SelectTrigger><SelectValue placeholder="No Signature" /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value="none">No Signature</SelectItem>
                    {signatures.map((s) => (
                      <SelectItem key={s.id} value={s.id}>
                        {s.name}{s.is_default ? " (default)" : ""}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                {signatureHtml && (
                  <div
                    className="text-xs text-muted-foreground border rounded p-2 bg-muted/30 max-h-24 overflow-hidden"
                    dangerouslySetInnerHTML={{ __html: signatureHtml }}
                  />
                )}
              </div>
              <div className="space-y-2">
                <Label>Subject Line <span className="text-destructive">*</span></Label>
                <Input placeholder="Subject..." value={subject} onChange={(e) => setSubject(e.target.value)} />
              </div>
            </CardContent>
          </Card>

          <Card>
            <Tabs value={tab} onValueChange={setTab}>
              <TabsList className="mx-6 mt-4">
                <TabsTrigger value="content" className="gap-2"><FileText className="h-4 w-4" /> Content</TabsTrigger>
                <TabsTrigger value="preview" className="gap-2"><Eye className="h-4 w-4" /> Final Preview</TabsTrigger>
              </TabsList>
              <TabsContent value="content" className="pt-2 px-4 pb-4">
                <RichEmailEditor value={content} onChange={setContent} placeholder="Write your email content. Use the toolbar to format text and embed images." />
              </TabsContent>
              <TabsContent value="preview" className="pt-2">
                <div
                  className="border rounded-lg p-6 bg-background min-h-[250px] prose max-w-none"
                  dangerouslySetInnerHTML={{
                    __html: composeBodyWithSignature(content) || '<p>No content to preview.</p>',
                  }}
                />
              </TabsContent>
            </Tabs>
          </Card>
        </div>

        <div className="space-y-6">
          <Card>
            <CardHeader><CardTitle>Variables & Attachments</CardTitle></CardHeader>
            <CardContent className="space-y-4">
              {variables.length > 0 ? (
                <div className="flex flex-wrap gap-2">
                  {variables.map((v) => <Badge key={v} variant="secondary">{v}</Badge>)}
                </div>
              ) : (
                <p className="text-sm text-muted-foreground">No variables detected in current content (e.g. {"{{name}}"}).</p>
              )}
              <div className="space-y-2">
                <Label>Attachments</Label>
                <label className="flex flex-col items-center justify-center border-2 border-dashed rounded-lg p-6 cursor-pointer hover:border-primary/50 transition-colors">
                  <Paperclip className="h-8 w-8 text-muted-foreground mb-2" />
                  <span className="text-sm text-muted-foreground">Click to upload or drag and drop</span>
                  <span className="text-xs text-muted-foreground">PDF, Images, Word, Excel (Max 25MB each)</span>
                  <input type="file" multiple className="hidden" onChange={handleFileChange} />
                </label>
                {attachments.length > 0 && (
                  <div className="space-y-1 mt-2">
                    {attachments.map((f, i) => (
                      <div key={i} className="text-sm text-foreground flex items-center gap-2">
                        <Paperclip className="h-3 w-3" /> {f.name}
                      </div>
                    ))}
                  </div>
                )}
              </div>
            </CardContent>
          </Card>
        </div>
      </div>

      <div className="flex justify-end gap-3">
        <Button variant="outline" onClick={() => { setRecipients(""); setCc(""); setBcc(""); setShowCc(false); setShowBcc(false); setSubject(""); setContent(""); setAttachments([]); setTemplateId("none"); }}>Cancel</Button>
        {sendMethod === "mailchimp" && (
          <Button variant="secondary" onClick={() => handleSendMailchimp(false)} disabled={sending || uploading}>
            {sending ? <Loader2 className="h-4 w-4 mr-2 animate-spin" /> : <Mail className="h-4 w-4 mr-2" />}
            Save as Draft in Mailchimp
          </Button>
        )}
        <Button onClick={handleSend} disabled={sending || uploading}>
          {sending || uploading ? <Loader2 className="h-4 w-4 mr-2 animate-spin" /> : (sendMethod === "mailchimp" ? <Mail className="h-4 w-4 mr-2" /> : <Send className="h-4 w-4 mr-2" />)}
          {sending || uploading ? "Sending..." : (sendMethod === "mailchimp" ? "Send via Mailchimp" : "Send Email")}
        </Button>
      </div>

      <OwnerEmailPicker
        open={pickerOpen !== null}
        onOpenChange={(v) => { if (!v) setPickerOpen(null); }}
        onConfirm={handlePickerConfirm}
      />

      <EmailSignatureManager
        open={signatureManagerOpen}
        onOpenChange={setSignatureManagerOpen}
        onChanged={(rows) => {
          setSignatures(rows);
          // If the currently selected one was deleted, fall back to default/none
          if (signatureId !== "none" && !rows.find((r) => r.id === signatureId)) {
            const def = rows.find((r) => r.is_default);
            setSignatureId(def?.id || "none");
            setSignatureHtml(def?.html || "");
          }
        }}
      />
    </div>
  );
}
