import { useEffect, useState } from "react";
import { supabase } from "@/integrations/supabase/client";
import { saveBillInvoiceToDocuments } from "@/lib/saveBillToDocuments";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
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 { Badge } from "@/components/ui/badge";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import {
  Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from "@/components/ui/select";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, DialogFooter,
} from "@/components/ui/dialog";
import { useToast } from "@/hooks/use-toast";
import { Mail, Plus, Trash2, ExternalLink, FileText, Copy } from "lucide-react";
import { format } from "date-fns";

interface VendorMapping {
  id: string;
  email: string;
  association_id: string;
  vendor_name: string | null;
  notes: string | null;
  associations?: { name: string } | null;
}

interface InboundEmail {
  id: string;
  from_email: string | null;
  from_name: string | null;
  subject: string | null;
  attachment_url: string | null;
  attachment_filename: string | null;
  parsed_data: Record<string, unknown> | null;
  status: string;
  error_message: string | null;
  association_id: string | null;
  bill_id: string | null;
  created_at: string;
  associations?: { name: string } | null;
}

interface Association { id: string; name: string }

const INBOUND_HOSTNAME_HINT = "bills.yourdomain.com";

export default function InboundBillsPage() {
  const { toast } = useToast();
  const [mappings, setMappings] = useState<VendorMapping[]>([]);
  const [emails, setEmails] = useState<InboundEmail[]>([]);
  const [associations, setAssociations] = useState<Association[]>([]);
  const [loading, setLoading] = useState(true);
  const [addOpen, setAddOpen] = useState(false);
  const [newMapping, setNewMapping] = useState({ email: "", association_id: "", vendor_name: "", notes: "" });

  const webhookUrl = `${import.meta.env.VITE_SUPABASE_URL}/functions/v1/inbound-bill-email`;

  async function load() {
    setLoading(true);
    const [m, e, a] = await Promise.all([
      supabase.from("vendor_email_mappings").select("*, associations(name)").order("created_at", { ascending: false }),
      supabase.from("inbound_bill_emails").select("*, associations(name)").order("created_at", { ascending: false }).limit(100),
      supabase.from("associations").select("id, name").order("name"),
    ]);
    if (m.data) setMappings(m.data as unknown as VendorMapping[]);
    if (e.data) setEmails(e.data as unknown as InboundEmail[]);
    if (a.data) setAssociations(a.data as Association[]);
    setLoading(false);
  }

  useEffect(() => { load(); }, []);

  async function addMapping() {
    if (!newMapping.email || !newMapping.association_id) {
      toast({ title: "Missing fields", description: "Email and association are required", variant: "destructive" });
      return;
    }
    const { error } = await supabase.from("vendor_email_mappings").insert({
      email: newMapping.email.trim().toLowerCase(),
      association_id: newMapping.association_id,
      vendor_name: newMapping.vendor_name || null,
      notes: newMapping.notes || null,
    });
    if (error) {
      toast({ title: "Failed to add", description: error.message, variant: "destructive" });
      return;
    }
    toast({ title: "Mapping added" });
    setAddOpen(false);
    setNewMapping({ email: "", association_id: "", vendor_name: "", notes: "" });
    load();
  }

  async function deleteMapping(id: string) {
    const { error } = await supabase.from("vendor_email_mappings").delete().eq("id", id);
    if (error) {
      toast({ title: "Failed", description: error.message, variant: "destructive" });
      return;
    }
    toast({ title: "Mapping removed" });
    load();
  }

  async function assignEmail(emailId: string, associationId: string) {
    // Set association on inbound row, then create a draft bill from parsed data.
    const email = emails.find(e => e.id === emailId);
    if (!email) return;

    const parsed = email.parsed_data || {};
    const totalAmount = Number((parsed as any).total_amount) || 0;
    const invoiceNumber = (parsed as any).invoice_number || null;
    const invoiceDate = (parsed as any).invoice_date || new Date().toISOString().slice(0, 10);
    const dueDate = (parsed as any).due_date || null;
    const vendorName = (parsed as any).vendor_name || email.from_name || email.from_email || "Unknown Vendor";

    const { data: bill, error: billErr } = await supabase
      .from("bills")
      .insert({
        association_id: associationId,
        amount: totalAmount,
        invoice_number: invoiceNumber,
        bill_date: invoiceDate,
        due_date: dueDate,
        description: `Inbound from ${vendorName} (${email.subject ?? "no subject"})`,
        attachment_url: email.attachment_url,
        status: "pending",
      })
      .select("id")
      .single();

    if (billErr || !bill) {
      toast({ title: "Bill creation failed", description: billErr?.message, variant: "destructive" });
      return;
    }

    await supabase
      .from("inbound_bill_emails")
      .update({
        association_id: associationId,
        bill_id: bill.id,
        status: "processed",
        processed_at: new Date().toISOString(),
      })
      .eq("id", emailId);

    saveBillInvoiceToDocuments({
      associationId,
      attachmentUrl: email.attachment_url,
      vendorName,
      invoiceNumber,
      invoiceDate,
    });

    toast({ title: "Bill created", description: `Assigned to ${associations.find(a => a.id === associationId)?.name ?? ""}` });
    load();
  }

  async function rejectEmail(id: string) {
    await supabase.from("inbound_bill_emails").update({ status: "rejected" }).eq("id", id);
    load();
  }

  function copyWebhook() {
    navigator.clipboard.writeText(webhookUrl);
    toast({ title: "Copied", description: "Webhook URL copied to clipboard" });
  }

  const unassigned = emails.filter(e => e.status === "unassigned");
  const processed = emails.filter(e => e.status !== "unassigned");

  return (
    <div className="container mx-auto py-6 space-y-6">
      <div>
        <h1 className="text-3xl font-bold">Inbound Bill Emails</h1>
        <p className="text-muted-foreground">Receive bills via email and auto-create them from PDF attachments.</p>
      </div>

      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2"><Mail className="w-5 h-5" /> SendGrid Inbound Parse Setup</CardTitle>
          <CardDescription>One-time configuration in SendGrid to forward inbound mail to this app.</CardDescription>
        </CardHeader>
        <CardContent className="space-y-3 text-sm">
          <ol className="list-decimal pl-5 space-y-2">
            <li>At your DNS provider, add an MX record for a dedicated subdomain (e.g. <code className="bg-muted px-1 rounded">{INBOUND_HOSTNAME_HINT}</code>) pointing to <code className="bg-muted px-1 rounded">mx.sendgrid.net</code> with priority 10.</li>
            <li>In SendGrid → Settings → Inbound Parse → Add Host & URL.</li>
            <li>Enter your subdomain as the hostname.</li>
            <li>Paste this Destination URL:
              <div className="flex items-center gap-2 mt-1">
                <code className="bg-muted px-2 py-1 rounded flex-1 break-all text-xs">{webhookUrl}</code>
                <Button size="sm" variant="outline" onClick={copyWebhook}><Copy className="w-3 h-3" /></Button>
              </div>
            </li>
            <li>Check <b>"POST the raw, full MIME message"</b> is OFF (we use parsed mode).</li>
            <li>Tell vendors to send invoices to any address at that domain (e.g. <code className="bg-muted px-1 rounded">bills@{INBOUND_HOSTNAME_HINT}</code>).</li>
          </ol>
        </CardContent>
      </Card>

      <Tabs defaultValue="inbox" className="w-full">
        <TabsList>
          <TabsTrigger value="inbox">Inbox {unassigned.length > 0 && <Badge variant="destructive" className="ml-2">{unassigned.length}</Badge>}</TabsTrigger>
          <TabsTrigger value="history">History</TabsTrigger>
          <TabsTrigger value="mappings">Vendor Mappings ({mappings.length})</TabsTrigger>
        </TabsList>

        <TabsContent value="inbox">
          <Card>
            <CardHeader>
              <CardTitle>Unassigned Emails</CardTitle>
              <CardDescription>Emails from senders without a vendor mapping. Pick the association to create the bill.</CardDescription>
            </CardHeader>
            <CardContent>
              {loading ? <p>Loading…</p> : unassigned.length === 0 ? (
                <p className="text-sm text-muted-foreground">No unassigned emails.</p>
              ) : (
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead>Received</TableHead>
                      <TableHead>From</TableHead>
                      <TableHead>Subject</TableHead>
                      <TableHead>Vendor (parsed)</TableHead>
                      <TableHead>Amount</TableHead>
                      <TableHead>PDF</TableHead>
                      <TableHead>Assign to</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {unassigned.map(e => {
                      const parsed = (e.parsed_data || {}) as Record<string, unknown>;
                      return (
                        <TableRow key={e.id}>
                          <TableCell className="text-xs">{format(new Date(e.created_at), "MMM d, p")}</TableCell>
                          <TableCell className="text-xs">{e.from_name ? `${e.from_name} <${e.from_email}>` : e.from_email}</TableCell>
                          <TableCell className="text-xs max-w-[200px] truncate">{e.subject}</TableCell>
                          <TableCell className="text-xs">{(parsed.vendor_name as string) || "—"}</TableCell>
                          <TableCell className="text-xs">{parsed.total_amount ? `$${Number(parsed.total_amount).toFixed(2)}` : "—"}</TableCell>
                          <TableCell>
                            {e.attachment_url ? (
                              <a href={e.attachment_url} target="_blank" rel="noreferrer" className="text-primary inline-flex items-center gap-1 text-xs">
                                <FileText className="w-3 h-3" /> View
                              </a>
                            ) : "—"}
                          </TableCell>
                          <TableCell>
                            <div className="flex gap-1">
                              <Select onValueChange={(v) => assignEmail(e.id, v)}>
                                <SelectTrigger className="w-[180px] h-8 text-xs"><SelectValue placeholder="Choose…" /></SelectTrigger>
                                <SelectContent>
                                  {associations.map(a => <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>)}
                                </SelectContent>
                              </Select>
                              <Button size="sm" variant="ghost" onClick={() => rejectEmail(e.id)}><Trash2 className="w-3 h-3" /></Button>
                            </div>
                          </TableCell>
                        </TableRow>
                      );
                    })}
                  </TableBody>
                </Table>
              )}
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="history">
          <Card>
            <CardHeader><CardTitle>Recent Inbound Emails</CardTitle></CardHeader>
            <CardContent>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Received</TableHead>
                    <TableHead>From</TableHead>
                    <TableHead>Subject</TableHead>
                    <TableHead>Association</TableHead>
                    <TableHead>Status</TableHead>
                    <TableHead>Bill</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {processed.map(e => (
                    <TableRow key={e.id}>
                      <TableCell className="text-xs">{format(new Date(e.created_at), "MMM d, p")}</TableCell>
                      <TableCell className="text-xs">{e.from_email}</TableCell>
                      <TableCell className="text-xs max-w-[200px] truncate">{e.subject}</TableCell>
                      <TableCell className="text-xs">{e.associations?.name ?? "—"}</TableCell>
                      <TableCell>
                        <Badge variant={e.status === "processed" ? "default" : e.status === "rejected" ? "destructive" : "secondary"}>{e.status}</Badge>
                      </TableCell>
                      <TableCell className="text-xs">
                        {e.bill_id ? (
                          <a href={`/dashboard/bills`} className="text-primary inline-flex items-center gap-1">
                            View <ExternalLink className="w-3 h-3" />
                          </a>
                        ) : "—"}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="mappings">
          <Card>
            <CardHeader className="flex flex-row items-center justify-between">
              <div>
                <CardTitle>Vendor Email → Association</CardTitle>
                <CardDescription>Maps a vendor's sending email address to an association. Inbound bills from these addresses are auto-created.</CardDescription>
              </div>
              <Dialog open={addOpen} onOpenChange={setAddOpen}>
                <DialogTrigger asChild><Button><Plus className="w-4 h-4 mr-1" /> Add Mapping</Button></DialogTrigger>
                <DialogContent>
                  <DialogHeader><DialogTitle>Add Vendor Email Mapping</DialogTitle></DialogHeader>
                  <div className="space-y-3">
                    <div>
                      <Label>Vendor email *</Label>
                      <Input value={newMapping.email} onChange={(e) => setNewMapping({ ...newMapping, email: e.target.value })} placeholder="billing@vendor.com" />
                    </div>
                    <div>
                      <Label>Association *</Label>
                      <Select value={newMapping.association_id} onValueChange={(v) => setNewMapping({ ...newMapping, association_id: v })}>
                        <SelectTrigger><SelectValue placeholder="Choose association" /></SelectTrigger>
                        <SelectContent>
                          {associations.map(a => <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>)}
                        </SelectContent>
                      </Select>
                    </div>
                    <div>
                      <Label>Vendor name (optional)</Label>
                      <Input value={newMapping.vendor_name} onChange={(e) => setNewMapping({ ...newMapping, vendor_name: e.target.value })} />
                    </div>
                    <div>
                      <Label>Notes (optional)</Label>
                      <Textarea value={newMapping.notes} onChange={(e) => setNewMapping({ ...newMapping, notes: e.target.value })} />
                    </div>
                  </div>
                  <DialogFooter>
                    <Button variant="outline" onClick={() => setAddOpen(false)}>Cancel</Button>
                    <Button onClick={addMapping}>Add</Button>
                  </DialogFooter>
                </DialogContent>
              </Dialog>
            </CardHeader>
            <CardContent>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Email</TableHead>
                    <TableHead>Association</TableHead>
                    <TableHead>Vendor</TableHead>
                    <TableHead>Notes</TableHead>
                    <TableHead></TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {mappings.map(m => (
                    <TableRow key={m.id}>
                      <TableCell>{m.email}</TableCell>
                      <TableCell>{m.associations?.name}</TableCell>
                      <TableCell>{m.vendor_name ?? "—"}</TableCell>
                      <TableCell className="text-xs text-muted-foreground">{m.notes ?? ""}</TableCell>
                      <TableCell>
                        <Button size="sm" variant="ghost" onClick={() => deleteMapping(m.id)}><Trash2 className="w-3 h-3" /></Button>
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </CardContent>
          </Card>
        </TabsContent>
      </Tabs>
    </div>
  );
}
