import { useMemo, useState } from "react";
import { formatDistanceToNow } from "date-fns";
import { AlertCircle, ArrowLeft, CheckCircle, Inbox, Loader2, Mail, MessageCircle, RefreshCw, Send, UserPlus, X } from "lucide-react";
import { supabase } from "@/integrations/supabase/client";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { useToast } from "@/hooks/use-toast";
import { cn } from "@/lib/utils";

type EmailLog = {
  id: string;
  message_id: string | null;
  template_name: string | null;
  recipient_email: string | null;
  status: string | null;
  error_message: string | null;
  created_at: string;
};

type InboxTicket = {
  id: string;
  source_id: string;
  source_type: string;
  title: string;
  submitter_name: string | null;
  submitter_email: string | null;
  summary: string | null;
  status: string;
  created_at: string;
};

type TicketComment = {
  id: string;
  comment: string;
  created_at: string;
  user_id: string;
  profile?: { full_name: string | null; email: string | null } | null;
};

const statusClass: Record<string, string> = {
  sent: "bg-success/10 text-success border-success/20",
  dlq: "bg-destructive/10 text-destructive border-destructive/20",
  failed: "bg-destructive/10 text-destructive border-destructive/20",
  bounced: "bg-destructive/10 text-destructive border-destructive/20",
  complained: "bg-destructive/10 text-destructive border-destructive/20",
  suppressed: "bg-warning/10 text-warning border-warning/20",
  pending: "bg-muted text-muted-foreground border-border",
};

const ticketStatusClass: Record<string, string> = {
  new: "bg-primary/10 text-primary border-primary/20",
  in_progress: "bg-warning/10 text-warning border-warning/20",
  closed: "bg-success/10 text-success border-success/20",
};

function latestByMessageId(rows: EmailLog[]) {
  const seen = new Map<string, EmailLog>();
  rows.forEach((row) => {
    const key = row.message_id || row.id;
    const current = seen.get(key);
    if (!current || new Date(row.created_at) > new Date(current.created_at)) seen.set(key, row);
  });
  return Array.from(seen.values()).sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
}

export function EmailInboxDrawer() {
  const { toast } = useToast();
  const [open, setOpen] = useState(false);
  const [loading, setLoading] = useState(false);
  const [commentsLoading, setCommentsLoading] = useState(false);
  const [sendingReply, setSendingReply] = useState(false);
  const [emails, setEmails] = useState<EmailLog[]>([]);
  const [tickets, setTickets] = useState<InboxTicket[]>([]);
  const [selectedTicket, setSelectedTicket] = useState<InboxTicket | null>(null);
  const [comments, setComments] = useState<TicketComment[]>([]);
  const [reply, setReply] = useState("");

  const fetchInbox = async () => {
    setLoading(true);
    const [emailRes, ticketRes] = await Promise.all([
      (supabase as any)
        .from("email_send_log")
        .select("id, message_id, template_name, recipient_email, status, error_message, created_at")
        .order("created_at", { ascending: false })
        .limit(200),
      supabase
        .from("form_inbox")
        .select("id, source_id, source_type, title, submitter_name, submitter_email, summary, status, created_at")
        .in("source_type", ["homeowner_ticket", "registration_request"])
        .neq("status", "archived")
        .order("created_at", { ascending: false })
        .limit(50),
    ]);

    if (emailRes.error || ticketRes.error) {
      setEmails([]);
      setTickets([]);
      toast({ variant: "destructive", title: "Inbox activity unavailable", description: emailRes.error?.message || ticketRes.error?.message });
    } else {
      setEmails(latestByMessageId((emailRes.data || []) as EmailLog[]));
      setTickets((ticketRes.data || []) as InboxTicket[]);
    }
    setLoading(false);
  };

  const stats = useMemo(() => ({
    total: emails.length + tickets.length,
    sent: emails.filter((email) => email.status === "sent").length,
    failed: tickets.length + emails.filter((email) => ["dlq", "failed", "bounced", "complained"].includes(email.status || "")).length,
  }), [emails, tickets]);

  const toggleOpen = () => {
    setOpen((current) => {
      const next = !current;
      if (next) void fetchInbox();
      return next;
    });
  };

  const fetchComments = async (ticketId: string) => {
    setCommentsLoading(true);
    const { data, error } = await supabase
      .from("entity_comments")
      .select("id, comment, created_at, user_id")
      .eq("entity_type", "homeowner_request")
      .eq("entity_id", ticketId)
      .order("created_at", { ascending: true });

    if (error) {
      setComments([]);
      toast({ variant: "destructive", title: "Could not load replies", description: error.message });
    } else {
      const userIds = [...new Set((data || []).map((comment) => comment.user_id).filter(Boolean))];
      const { data: profiles } = userIds.length
        ? await supabase.from("profiles").select("user_id, full_name, email").in("user_id", userIds)
        : { data: [] };
      const profileMap = new Map((profiles || []).map((profile) => [profile.user_id, profile]));
      setComments((data || []).map((comment) => ({ ...comment, profile: profileMap.get(comment.user_id) || null })) as TicketComment[]);
    }
    setCommentsLoading(false);
  };

  const openTicket = async (ticket: InboxTicket) => {
    const nextTicket = ticket.status === "new" ? { ...ticket, status: "in_progress" } : ticket;
    setSelectedTicket(nextTicket);
    setReply("");
    if (ticket.source_type === "registration_request") {
      if (ticket.status === "new") {
        setTickets((current) => current.map((item) => item.id === ticket.id ? nextTicket : item));
        void supabase.from("form_inbox").update({ status: "in_progress", reviewed_at: new Date().toISOString() } as any).eq("id", ticket.id);
      }
      setComments([]);
      return;
    }
    if (ticket.status === "new") {
      setTickets((current) => current.map((item) => item.id === ticket.id ? nextTicket : item));
      void supabase.from("form_inbox").update({ status: "in_progress", reviewed_at: new Date().toISOString() } as any).eq("id", ticket.id);
    }
    await fetchComments(ticket.source_id);
  };

  const closeTicket = async () => {
    if (!selectedTicket) return;
    const { error: inboxError } = await supabase
      .from("form_inbox")
      .update({ status: "closed", reviewed_at: new Date().toISOString() } as any)
      .eq("id", selectedTicket.id);
    const { error: ticketError } = selectedTicket.source_type === "homeowner_ticket"
      ? await supabase.from("homeowner_requests").update({ status: "closed" } as any).eq("id", selectedTicket.source_id)
      : { error: null };

    if (inboxError || ticketError) {
      toast({ variant: "destructive", title: "Ticket not closed", description: inboxError?.message || ticketError?.message });
      return;
    }

    setTickets((current) => current.map((item) => item.id === selectedTicket.id ? { ...item, status: "closed" } : item));
    setSelectedTicket((current) => current ? { ...current, status: "closed" } : current);
    toast({ title: "Ticket closed" });
  };

  const sendReply = async () => {
    if (!selectedTicket || !reply.trim()) return;
    setSendingReply(true);
    const { data: userRes } = await supabase.auth.getUser();
    const userId = userRes.user?.id;
    if (!userId) {
      setSendingReply(false);
      toast({ variant: "destructive", title: "Please sign in to reply" });
      return;
    }

    const message = reply.trim();
    const { error } = await supabase.from("entity_comments").insert({
      entity_type: "homeowner_request",
      entity_id: selectedTicket.source_id,
      user_id: userId,
      comment: message,
    });

    if (error) {
      toast({ variant: "destructive", title: "Reply not sent", description: error.message });
    } else {
      setReply("");
      toast({ title: "Reply sent", description: "The homeowner has been notified." });
      if (selectedTicket.submitter_email) {
        void supabase.functions.invoke("send-transactional-email", {
          body: {
            templateName: "ticket-response",
            recipientEmail: selectedTicket.submitter_email,
            idempotencyKey: `ticket-response-${selectedTicket.source_id}-${Date.now()}`,
            templateData: {
              ticketTitle: selectedTicket.title,
              message,
              homeownerName: selectedTicket.submitter_name || "Homeowner",
            },
          },
        });
      }
      await fetchComments(selectedTicket.source_id);
    }
    setSendingReply(false);
  };

  return (
    <>
      <Button
        variant="ghost"
        size="sm"
        className="h-7 w-7 p-0 text-muted-foreground hover:text-foreground"
        onClick={toggleOpen}
        aria-expanded={open}
        aria-controls="email-inbox-popout"
      >
        <Mail className="h-3.5 w-3.5" />
        <span className="sr-only">Open in-app mail inbox</span>
      </Button>

      {open && (
        <aside
          id="email-inbox-popout"
          className="fixed bottom-4 right-4 z-50 flex h-[min(640px,calc(100vh-5rem))] w-[min(600px,calc(100vw-2rem))] flex-col overflow-hidden rounded-lg border border-border bg-card shadow-2xl"
          aria-label="In-app mail inbox"
        >
          <div className="border-b border-border px-5 py-4 text-left">
            <div className="flex items-center justify-between gap-3 pr-8">
              <div>
                <h2 className="flex items-center gap-2 text-base font-semibold text-foreground">
                  <Inbox className="h-4 w-4 text-primary" /> In-App Mail
                </h2>
                <p className="text-sm text-muted-foreground">Review system mail activity and use notifications for incoming in-app messages.</p>
              </div>
              <div className="flex items-center gap-2">
                <Button variant="outline" size="sm" className="h-8 gap-1.5" onClick={fetchInbox} disabled={loading}>
                  {loading ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <RefreshCw className="h-3.5 w-3.5" />}
                  Refresh
                </Button>
                <Button variant="ghost" size="icon" className="h-8 w-8" onClick={() => setOpen(false)}>
                  <X className="h-4 w-4" />
                  <span className="sr-only">Close in-app mail</span>
                </Button>
              </div>
            </div>
          </div>

          <div className="grid grid-cols-3 gap-2 border-b border-border p-4">
            <div className="rounded-md border border-border bg-card p-3"><p className="text-xs text-muted-foreground">Total</p><p className="text-xl font-semibold text-foreground">{stats.total}</p></div>
            <div className="rounded-md border border-border bg-card p-3"><p className="text-xs text-muted-foreground">Sent</p><p className="text-xl font-semibold text-foreground">{stats.sent}</p></div>
            <div className="rounded-md border border-border bg-card p-3"><p className="text-xs text-muted-foreground">Needs review</p><p className="text-xl font-semibold text-foreground">{stats.failed}</p></div>
          </div>

          <div className="min-h-0 flex-1 overflow-y-auto">
            {selectedTicket ? (
              <div className="space-y-4 p-5">
                <Button variant="ghost" size="sm" className="h-8 gap-2 px-2" onClick={() => setSelectedTicket(null)}>
                  <ArrowLeft className="h-4 w-4" /> Back to inbox
                </Button>
                <div className="rounded-md border border-border bg-card p-4">
                  <div className="flex items-start justify-between gap-3">
                    <div className="min-w-0">
                      <h3 className="text-sm font-semibold text-foreground">{selectedTicket.title}</h3>
                      <p className="mt-1 text-xs text-muted-foreground">{selectedTicket.submitter_name || selectedTicket.submitter_email || "Homeowner ticket"}</p>
                    </div>
                    <div className="flex shrink-0 items-center gap-2">
                      <Badge variant="outline" className={cn("capitalize", ticketStatusClass[selectedTicket.status] || ticketStatusClass.in_progress)}>{selectedTicket.status.replace("_", " ")}</Badge>
                      {selectedTicket.status !== "closed" && (
                        <Button variant="outline" size="sm" className="h-8 gap-1.5" onClick={closeTicket}>
                          <CheckCircle className="h-3.5 w-3.5" /> Close
                        </Button>
                      )}
                    </div>
                  </div>
                  {selectedTicket.summary && <p className="mt-3 whitespace-pre-line text-sm text-muted-foreground">{selectedTicket.summary}</p>}
                  <p className="mt-3 text-xs text-muted-foreground">Submitted {formatDistanceToNow(new Date(selectedTicket.created_at), { addSuffix: true })}</p>
                </div>
                <div className="space-y-3">
                  {selectedTicket.source_type === "homeowner_ticket" && <h4 className="flex items-center gap-2 text-sm font-semibold text-foreground"><MessageCircle className="h-4 w-4 text-primary" /> Responses</h4>}
                  {selectedTicket.source_type !== "homeowner_ticket" ? (
                    <p className="rounded-md border border-border bg-muted/30 p-3 text-sm text-muted-foreground">Open Form Inbox to review and process this registration request.</p>
                  ) : commentsLoading ? (
                    <div className="flex items-center gap-2 text-sm text-muted-foreground"><Loader2 className="h-4 w-4 animate-spin" /> Loading replies…</div>
                  ) : comments.length === 0 ? (
                    <p className="rounded-md border border-border bg-muted/30 p-3 text-sm text-muted-foreground">No responses yet.</p>
                  ) : (
                    <div className="space-y-3">
                      {comments.map((comment) => (
                        <div key={comment.id} className="rounded-md border border-border bg-card p-3">
                          <div className="mb-1 flex justify-between gap-3 text-xs text-muted-foreground">
                            <span>{comment.profile?.full_name || comment.profile?.email || "User"}</span>
                            <span>{formatDistanceToNow(new Date(comment.created_at), { addSuffix: true })}</span>
                          </div>
                          <p className="whitespace-pre-wrap text-sm text-foreground">{comment.comment}</p>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
                {selectedTicket.source_type === "homeowner_ticket" && (
                  <div className="space-y-2 border-t border-border pt-4">
                    <Textarea value={reply} onChange={(event) => setReply(event.target.value)} placeholder="Write a response to the homeowner..." className="min-h-[96px]" maxLength={1500} />
                    <Button className="w-full gap-2" onClick={sendReply} disabled={!reply.trim() || sendingReply}>
                      {sendingReply ? <Loader2 className="h-4 w-4 animate-spin" /> : <Send className="h-4 w-4" />} Send response
                    </Button>
                  </div>
                )}
              </div>
            ) : loading ? (
              <div className="flex h-full items-center justify-center gap-2 text-sm text-muted-foreground"><Loader2 className="h-4 w-4 animate-spin" /> Loading mail activity…</div>
            ) : emails.length === 0 && tickets.length === 0 ? (
              <div className="flex h-full flex-col items-center justify-center px-6 text-center text-muted-foreground"><Inbox className="mb-3 h-9 w-9 opacity-40" /><p className="text-sm font-medium text-foreground">No mail activity found</p><p className="mt-1 text-xs">Homeowner tickets, ticket replies, and direct messages arrive through in-app notifications.</p></div>
            ) : (
              <div className="divide-y divide-border">
                {tickets.map((ticket) => (
                  <button key={ticket.id} type="button" className="block w-full px-5 py-4 text-left hover:bg-muted/40" onClick={() => void openTicket(ticket)}>
                    <div className="flex items-start justify-between gap-3">
                      <div className="min-w-0 flex-1">
                        <p className="flex items-center gap-2 truncate text-sm font-medium text-foreground">{ticket.source_type === "registration_request" ? <UserPlus className="h-3.5 w-3.5 text-primary" /> : <MessageCircle className="h-3.5 w-3.5 text-primary" />} {ticket.title}</p>
                        <p className="truncate text-xs text-muted-foreground">{ticket.submitter_name || ticket.submitter_email || (ticket.source_type === "registration_request" ? "Registration request" : "Homeowner ticket")}</p>
                      </div>
                      <Badge variant="outline" className={cn("capitalize", ticketStatusClass[ticket.status] || ticketStatusClass.in_progress)}>{ticket.status.replace("_", " ")}</Badge>
                    </div>
                    {ticket.summary && <p className="mt-2 line-clamp-2 text-xs text-muted-foreground whitespace-pre-line">{ticket.summary}</p>}
                    <div className="mt-2 text-xs text-muted-foreground">{formatDistanceToNow(new Date(ticket.created_at), { addSuffix: true })}</div>
                  </button>
                ))}
                {emails.map((email) => {
                  const status = email.status || "pending";
                  const hasError = Boolean(email.error_message);
                  return (
                    <div key={email.id} className="px-5 py-4 hover:bg-muted/40">
                      <div className="flex items-start justify-between gap-3">
                        <div className="min-w-0 flex-1"><p className="truncate text-sm font-medium text-foreground">{email.template_name || "Email"}</p><p className="truncate text-xs text-muted-foreground">{email.recipient_email || "No recipient"}</p></div>
                        <Badge variant="outline" className={cn("capitalize", statusClass[status] || statusClass.pending)}>{status === "dlq" ? "Failed" : status}</Badge>
                      </div>
                      <div className="mt-2 flex items-center justify-between gap-3 text-xs text-muted-foreground"><span>{formatDistanceToNow(new Date(email.created_at), { addSuffix: true })}</span>{hasError && <span className="flex items-center gap-1 text-destructive"><AlertCircle className="h-3 w-3" /> Error</span>}</div>
                      {hasError && <p className="mt-2 rounded-md bg-muted px-3 py-2 text-xs text-muted-foreground">{email.error_message}</p>}
                    </div>
                  );
                })}
              </div>
            )}
          </div>
        </aside>
      )}
    </>
  );
}