import { useEffect, useState } from "react";
import { supabase } from "@/integrations/supabase/client";
import { Card, CardContent, CardHeader, CardTitle } 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 { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Badge } from "@/components/ui/badge";
import { useToast } from "@/hooks/use-toast";
import { Copy, Plus, Trash2, RefreshCw, Link as LinkIcon, Download, Layers, Mail, Check, ChevronsUpDown } from "lucide-react";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { cn } from "@/lib/utils";
import { format } from "date-fns";

type SignupCode = {
  id: string;
  code: string;
  role: string;
  owner_id: string | null;
  association_id: string | null;
  rental_id: string | null;
  note: string | null;
  expires_at: string | null;
  redeemed_at: string | null;
  redeemed_email: string | null;
  created_at: string;
};

type OwnerOption = { id: string; first_name: string | null; last_name: string | null; email: string | null; association_id: string | null; unit_id: string | null };
type AssociationOption = { id: string; name: string };
type RentalOption = {
  id: string;
  renter_name: string | null;
  renter_email: string | null;
  association_id: string | null;
  lot_id: string | null;
  is_owner: boolean | null;
};

const ROLES = [
  { value: "homeowner", label: "Homeowner" },
  { value: "board_member", label: "Board Member" },
  { value: "rv_boat_lot", label: "RV/Boat Lot" },
  { value: "manager", label: "Manager" },
  { value: "admin", label: "Admin" },
  { value: "legal", label: "Legal" },
];

function generateCode() {
  const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
  let out = "";
  for (let i = 0; i < 10; i++) out += chars[Math.floor(Math.random() * chars.length)];
  return out;
}

export default function SignupCodesPage() {
  const { toast } = useToast();
  const [codes, setCodes] = useState<SignupCode[]>([]);
  const [owners, setOwners] = useState<OwnerOption[]>([]);
  const [associations, setAssociations] = useState<AssociationOption[]>([]);
  const [rentals, setRentals] = useState<RentalOption[]>([]);
  const [loading, setLoading] = useState(true);
  const [open, setOpen] = useState(false);
  const [bulkOpen, setBulkOpen] = useState(false);

  const [form, setForm] = useState({
    code: generateCode(),
    role: "homeowner",
    owner_id: "none",
    association_id: "none",
    rental_id: "none",
    note: "",
    expires_at: "",
  });

  const [bulkForm, setBulkForm] = useState({
    mode: "count" as "count" | "per_owner" | "per_unit",
    count: 10,
    role: "homeowner",
    association_id: "none",
    note: "",
    expires_at: "",
  });
  const [bulkLoading, setBulkLoading] = useState(false);

  const [ownersLoading, setOwnersLoading] = useState(false);
  const [ownersAssocId, setOwnersAssocId] = useState<string | null>(null);

  const fetchAll = async () => {
    setLoading(true);
    const [{ data: codeData }, { data: assocData }, { data: rentalData }] = await Promise.all([
      supabase.from("signup_codes").select("*").order("created_at", { ascending: false }),
      supabase.from("associations").select("id, name").order("name"),
      supabase
        .from("rv_boat_lot_rentals")
        .select("id, renter_name, renter_email, association_id, lot_id, is_owner")
        .eq("status", "active")
        .order("start_date", { ascending: false }),
    ]);
    setCodes((codeData as any) || []);
    setAssociations((assocData as any) || []);
    setRentals((rentalData as any) || []);

    // Fetch only owners referenced by existing codes (for table labels)
    const ownerIds = Array.from(new Set(((codeData as any[]) || []).map(c => c.owner_id).filter(Boolean)));
    if (ownerIds.length > 0) {
      const { data: ownerData } = await supabase
        .from("owners")
        .select("id, first_name, last_name, email, association_id, unit_id")
        .in("id", ownerIds);
      setOwners((prev) => {
        const map = new Map(prev.map(o => [o.id, o]));
        for (const o of (ownerData as any[]) || []) map.set(o.id, o);
        return Array.from(map.values());
      });
    }
    setLoading(false);
  };

  const loadOwnersForAssociation = async (assocId: string) => {
    if (!assocId || assocId === "none") return;
    if (ownersAssocId === assocId) return;
    setOwnersLoading(true);
    const { data } = await supabase
      .from("owners")
      .select("id, first_name, last_name, email, association_id, unit_id")
      .eq("association_id", assocId)
      .eq("status", "active")
      .order("last_name");
    setOwners((prev) => {
      const map = new Map(prev.map(o => [o.id, o]));
      for (const o of (data as any[]) || []) map.set(o.id, o);
      return Array.from(map.values());
    });
    setOwnersAssocId(assocId);
    setOwnersLoading(false);
  };

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

  const isRvRole = form.role === "rv_renter" || form.role === "rv_owner";

  const handleCreate = async () => {
    const payload: any = {
      code: form.code.trim().toUpperCase(),
      role: form.role,
      owner_id: form.owner_id === "none" ? null : form.owner_id,
      association_id: form.association_id === "none" ? null : form.association_id,
      rental_id: isRvRole && form.rental_id !== "none" ? form.rental_id : null,
      note: form.note || null,
      expires_at: form.expires_at ? new Date(form.expires_at).toISOString() : null,
      created_by: (await supabase.auth.getUser()).data.user?.id,
    };
    const { error } = await supabase.from("signup_codes").insert(payload);
    if (error) {
      toast({ title: "Failed to create code", description: error.message, variant: "destructive" });
      return;
    }
    toast({ title: "Sign-up code created" });
    setOpen(false);
    setForm({ code: generateCode(), role: "homeowner", owner_id: "none", association_id: "none", rental_id: "none", note: "", expires_at: "" });
    fetchAll();
  };

  const handleDelete = async (id: string) => {
    if (!confirm("Delete this sign-up code?")) return;
    const { error } = await supabase.from("signup_codes").delete().eq("id", id);
    if (error) {
      toast({ title: "Failed", description: error.message, variant: "destructive" });
      return;
    }
    toast({ title: "Deleted" });
    fetchAll();
  };

  const buildLink = (code: string) => `${window.location.origin}/register/${code}`;

  const copyLink = async (code: string) => {
    await navigator.clipboard.writeText(buildLink(code));
    toast({ title: "Registration link copied" });
  };

  const copyCode = async (code: string) => {
    await navigator.clipboard.writeText(code);
    toast({ title: "Code copied" });
  };

  const ROLE_LABELS: Record<string, string> = {
    homeowner: "Homeowner",
    board_member: "Board Member",
    rv_boat_lot: "RV/Boat Lot",
    rv_renter: "RV/Boat Renter",
    rv_owner: "RV/Boat Owner",
    manager: "Manager",
    admin: "Admin",
    legal: "Legal",
    association_management: "Association Management",
  };

  const emailCode = async (c: SignupCode) => {
    const owner = c.owner_id ? owners.find(o => o.id === c.owner_id) : null;
    const rental = c.rental_id ? rentals.find(r => r.id === c.rental_id) : null;
    const defaultEmail = owner?.email || rental?.renter_email || c.redeemed_email || "";
    const recipient = window.prompt("Send registration link to which email?", defaultEmail);
    if (!recipient) return;
    const trimmed = recipient.trim();
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(trimmed)) {
      toast({ title: "Invalid email", variant: "destructive" });
      return;
    }
    const recipientName = owner
      ? `${owner.first_name || ""} ${owner.last_name || ""}`.trim() || undefined
      : rental?.renter_name || undefined;
    const assocName = associationName(c.association_id);
    const expiresAt = c.expires_at ? format(new Date(c.expires_at), "MMMM d, yyyy") : undefined;
    const { error } = await supabase.functions.invoke("send-transactional-email", {
      body: {
        templateName: "signup-code-invite",
        recipientEmail: trimmed,
        idempotencyKey: `signup-code-${c.id}-${trimmed}`,
        templateData: {
          recipientName,
          associationName: assocName || undefined,
          code: c.code,
          link: buildLink(c.code),
          roleLabel: ROLE_LABELS[c.role] || c.role,
          expiresAt,
        },
      },
    });
    if (error) {
      toast({ title: "Failed to send", description: error.message, variant: "destructive" });
      return;
    }
    toast({ title: "Registration link emailed", description: `Sent to ${trimmed}` });
  };

  const ownerLabel = (id: string | null) => {
    if (!id) return "—";
    const o = owners.find(x => x.id === id);
    if (!o) return "Unknown";
    return `${o.first_name || ""} ${o.last_name || ""}`.trim() || o.email || "Unnamed";
  };

  const associationName = (id: string | null) => {
    if (!id) return "";
    return associations.find(a => a.id === id)?.name || "";
  };

  const handleBulkCreate = async () => {
    setBulkLoading(true);
    try {
      const userId = (await supabase.auth.getUser()).data.user?.id;
      const baseAssocId = bulkForm.association_id === "none" ? null : bulkForm.association_id;
      const expiresAt = bulkForm.expires_at ? new Date(bulkForm.expires_at).toISOString() : null;

      let payload: any[] = [];

      if (bulkForm.mode === "per_owner") {
        if (!baseAssocId) {
          toast({ title: "Pick an association", description: "Per-owner mode needs an association.", variant: "destructive" });
          setBulkLoading(false);
          return;
        }
        const targetOwners = owners.filter(o => o.association_id === baseAssocId);
        if (targetOwners.length === 0) {
          toast({ title: "No owners", description: "No active owners found for this association.", variant: "destructive" });
          setBulkLoading(false);
          return;
        }
        payload = targetOwners.map(o => ({
          code: generateCode(),
          role: bulkForm.role,
          owner_id: o.id,
          association_id: baseAssocId,
          rental_id: null,
          note: bulkForm.note || null,
          expires_at: expiresAt,
          created_by: userId,
        }));
      } else if (bulkForm.mode === "per_unit") {
        if (!baseAssocId) {
          toast({ title: "Pick an association", description: "Per-unit mode needs an association.", variant: "destructive" });
          setBulkLoading(false);
          return;
        }
        // One code per unique unit_id in this association.
        // Pin to the first active owner of each unit (so redeem links the user to the unit).
        const ownersInAssoc = owners.filter(o => o.association_id === baseAssocId && o.unit_id);
        const seenUnits = new Set<string>();
        const perUnitOwners: typeof ownersInAssoc = [];
        for (const o of ownersInAssoc) {
          if (!seenUnits.has(o.unit_id!)) {
            seenUnits.add(o.unit_id!);
            perUnitOwners.push(o);
          }
        }
        if (perUnitOwners.length === 0) {
          toast({ title: "No units", description: "No active owners with linked units found for this association.", variant: "destructive" });
          setBulkLoading(false);
          return;
        }
        payload = perUnitOwners.map(o => ({
          code: generateCode(),
          role: bulkForm.role,
          owner_id: o.id,
          association_id: baseAssocId,
          rental_id: null,
          note: bulkForm.note || null,
          expires_at: expiresAt,
          created_by: userId,
        }));
      } else {
        const n = Math.min(Math.max(parseInt(String(bulkForm.count)) || 0, 1), 1000);
        for (let i = 0; i < n; i++) {
          payload.push({
            code: generateCode(),
            role: bulkForm.role,
            owner_id: null,
            association_id: baseAssocId,
            rental_id: null,
            note: bulkForm.note || null,
            expires_at: expiresAt,
            created_by: userId,
          });
        }
      }

      const chunkSize = 200;
      for (let i = 0; i < payload.length; i += chunkSize) {
        const chunk = payload.slice(i, i + chunkSize);
        const { error } = await supabase.from("signup_codes").insert(chunk);
        if (error) throw error;
      }

      toast({ title: `Created ${payload.length} codes` });
      setBulkOpen(false);
      fetchAll();
    } catch (e: any) {
      toast({ title: "Bulk create failed", description: e.message, variant: "destructive" });
    } finally {
      setBulkLoading(false);
    }
  };

  const exportCsv = () => {
    if (codes.length === 0) {
      toast({ title: "No codes to export" });
      return;
    }
    const headers = [
      "code", "role", "association", "pinned_owner", "pinned_owner_email",
      "status", "redeemed_email", "redeemed_at", "expires_at",
      "note", "created_at", "registration_url",
    ];
    const rows = codes.map(c => {
      const owner = c.owner_id ? owners.find(o => o.id === c.owner_id) : null;
      const ownerName = owner ? `${owner.first_name || ""} ${owner.last_name || ""}`.trim() : "";
      const expired = c.expires_at && new Date(c.expires_at) < new Date();
      const status = c.redeemed_at ? "used" : expired ? "expired" : "active";
      return [
        c.code,
        c.role,
        associationName(c.association_id),
        ownerName,
        owner?.email || "",
        status,
        c.redeemed_email || "",
        c.redeemed_at || "",
        c.expires_at || "",
        c.note || "",
        c.created_at,
        `${window.location.origin}/register/${c.code}`,
      ];
    });
    const escape = (v: any) => {
      const s = String(v ?? "");
      return /[",\n\r]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
    };
    const csv = [headers, ...rows].map(r => r.map(escape).join(",")).join("\n");
    const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `signup-codes-${format(new Date(), "yyyy-MM-dd")}.csv`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  };

  return (
    <div className="space-y-6 p-6">
      <div className="flex items-start justify-between gap-4">
        <div>
          <h1 className="text-2xl font-bold">Sign-up Codes</h1>
          <p className="text-muted-foreground text-sm mt-1">
            Generate single-use registration codes. Owners who use a code at <code className="bg-muted px-1.5 py-0.5 rounded">/register/[code]</code> will have their email auto-verified.
          </p>
        </div>
        <div className="flex gap-2 flex-wrap">
          <Button variant="outline" onClick={fetchAll}><RefreshCw className="h-4 w-4 mr-2" />Refresh</Button>
          <Button variant="outline" onClick={exportCsv}><Download className="h-4 w-4 mr-2" />Export CSV</Button>
          <Dialog open={bulkOpen} onOpenChange={setBulkOpen}>
            <DialogTrigger asChild>
              <Button variant="secondary"><Layers className="h-4 w-4 mr-2" />Bulk Generate</Button>
            </DialogTrigger>
            <DialogContent>
              <DialogHeader>
                <DialogTitle>Bulk Generate Sign-up Codes</DialogTitle>
                <DialogDescription>Create many codes at once. Choose a count or one per active owner in an association.</DialogDescription>
              </DialogHeader>
              <div className="space-y-4">
                <div>
                  <Label>Mode</Label>
                  <Select value={bulkForm.mode} onValueChange={(v) => setBulkForm({ ...bulkForm, mode: v as any })}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      <SelectItem value="count">Generate a fixed number of codes</SelectItem>
                      <SelectItem value="per_owner">One code per active owner (pinned)</SelectItem>
                      <SelectItem value="per_unit">One code per unit (pinned to one owner)</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
                {bulkForm.mode === "count" && (
                  <div>
                    <Label>How many codes? (1-1000)</Label>
                    <Input
                      type="number"
                      min={1}
                      max={1000}
                      value={bulkForm.count}
                      onChange={(e) => setBulkForm({ ...bulkForm, count: parseInt(e.target.value) || 0 })}
                    />
                  </div>
                )}
                <div>
                  <Label>Role</Label>
                  <Select value={bulkForm.role} onValueChange={(v) => setBulkForm({ ...bulkForm, role: v })}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {ROLES.map(r => <SelectItem key={r.value} value={r.value}>{r.label}</SelectItem>)}
                    </SelectContent>
                  </Select>
                </div>
                <div>
                  <Label>Association {bulkForm.mode !== "count" ? "(required)" : "(optional)"}</Label>
                  <Select value={bulkForm.association_id} onValueChange={(v) => { setBulkForm({ ...bulkForm, association_id: v }); if (v !== "none") loadOwnersForAssociation(v); }}>
                    <SelectTrigger><SelectValue placeholder="None" /></SelectTrigger>
                    <SelectContent>
                      <SelectItem value="none">None</SelectItem>
                      {associations.map(a => <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>)}
                    </SelectContent>
                  </Select>
                  {bulkForm.mode === "per_owner" && bulkForm.association_id !== "none" && (
                    <p className="text-xs text-muted-foreground mt-1">
                      Will create {owners.filter(o => o.association_id === bulkForm.association_id).length} codes (one per active owner).
                    </p>
                  )}
                  {bulkForm.mode === "per_unit" && bulkForm.association_id !== "none" && (
                    <p className="text-xs text-muted-foreground mt-1">
                      Will create {new Set(owners.filter(o => o.association_id === bulkForm.association_id && o.unit_id).map(o => o.unit_id!)).size} codes (one per unit, pinned to one owner of that unit).
                    </p>
                  )}
                </div>
                <div>
                  <Label>Expires (optional)</Label>
                  <Input type="datetime-local" value={bulkForm.expires_at} onChange={(e) => setBulkForm({ ...bulkForm, expires_at: e.target.value })} />
                </div>
                <div>
                  <Label>Note (optional)</Label>
                  <Textarea value={bulkForm.note} onChange={(e) => setBulkForm({ ...bulkForm, note: e.target.value })} rows={2} />
                </div>
              </div>
              <DialogFooter>
                <Button variant="outline" onClick={() => setBulkOpen(false)} disabled={bulkLoading}>Cancel</Button>
                <Button onClick={handleBulkCreate} disabled={bulkLoading}>
                  {bulkLoading ? "Creating…" : "Generate"}
                </Button>
              </DialogFooter>
            </DialogContent>
          </Dialog>
          <Dialog open={open} onOpenChange={setOpen}>
            <DialogTrigger asChild>
              <Button><Plus className="h-4 w-4 mr-2" />New Code</Button>
            </DialogTrigger>
            <DialogContent>
              <DialogHeader>
                <DialogTitle>Create Sign-up Code</DialogTitle>
                <DialogDescription>Generate a single-use, auto-verifying registration code.</DialogDescription>
              </DialogHeader>
              <div className="space-y-4">
                <div>
                  <Label>Code</Label>
                  <div className="flex gap-2">
                    <Input value={form.code} onChange={(e) => setForm({ ...form, code: e.target.value.toUpperCase() })} className="font-mono" />
                    <Button type="button" variant="outline" onClick={() => setForm({ ...form, code: generateCode() })}>
                      <RefreshCw className="h-4 w-4" />
                    </Button>
                  </div>
                </div>
                <div>
                  <Label>Role</Label>
                  <Select value={form.role} onValueChange={(v) => setForm({ ...form, role: v })}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {ROLES.map(r => <SelectItem key={r.value} value={r.value}>{r.label}</SelectItem>)}
                    </SelectContent>
                  </Select>
                </div>
                <div>
                  <Label>Association</Label>
                  <Select
                    value={form.association_id}
                    onValueChange={(v) => {
                      setForm({ ...form, association_id: v, owner_id: "none" });
                      if (v !== "none") loadOwnersForAssociation(v);
                    }}
                  >
                    <SelectTrigger><SelectValue placeholder="Select an association first" /></SelectTrigger>
                    <SelectContent>
                      <SelectItem value="none">None</SelectItem>
                      {associations.map(a => <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>)}
                    </SelectContent>
                  </Select>
                  <p className="text-xs text-muted-foreground mt-1">Pick an association to load its owners.</p>
                </div>
                <div>
                  <Label>Pin to Owner (optional)</Label>
                  {form.association_id === "none" ? (
                    <p className="text-xs text-muted-foreground py-2">Select an association first.</p>
                  ) : ownersLoading ? (
                    <p className="text-xs text-muted-foreground py-2">Loading owners…</p>
                  ) : (
                    <OwnerCombobox
                      owners={owners.filter(o => o.association_id === form.association_id)}
                      value={form.owner_id}
                      onChange={(v) => setForm({ ...form, owner_id: v })}
                    />
                  )}
                </div>
                {isRvRole && (
                  <div>
                    <Label>Pin to RV/Boat Rental (recommended)</Label>
                    <Select value={form.rental_id} onValueChange={(v) => setForm({ ...form, rental_id: v })}>
                      <SelectTrigger><SelectValue placeholder="None" /></SelectTrigger>
                      <SelectContent className="max-h-60">
                        <SelectItem value="none">None</SelectItem>
                        {rentals
                          .filter(r => form.association_id === "none" || r.association_id === form.association_id)
                          .map(r => (
                            <SelectItem key={r.id} value={r.id}>
                              {r.renter_name || "Unnamed"} {r.renter_email ? `(${r.renter_email})` : ""}
                            </SelectItem>
                          ))}
                      </SelectContent>
                    </Select>
                    <p className="text-xs text-muted-foreground mt-1">
                      Links this account to the rental on redemption so it shows up in their portal.
                    </p>
                  </div>
                )}
                <div>
                  <Label>Expires (optional)</Label>
                  <Input type="datetime-local" value={form.expires_at} onChange={(e) => setForm({ ...form, expires_at: e.target.value })} />
                </div>
                <div>
                  <Label>Note (optional)</Label>
                  <Textarea value={form.note} onChange={(e) => setForm({ ...form, note: e.target.value })} rows={2} />
                </div>
              </div>
              <DialogFooter>
                <Button variant="outline" onClick={() => setOpen(false)}>Cancel</Button>
                <Button onClick={handleCreate}>Create</Button>
              </DialogFooter>
            </DialogContent>
          </Dialog>
        </div>
      </div>

      <Card>
        <CardHeader><CardTitle>Codes</CardTitle></CardHeader>
        <CardContent>
          {loading ? (
            <div className="text-muted-foreground py-8 text-center">Loading…</div>
          ) : codes.length === 0 ? (
            <div className="text-muted-foreground py-8 text-center">No codes yet.</div>
          ) : (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Code</TableHead>
                  <TableHead>Role</TableHead>
                  <TableHead>Pinned Owner</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead>Expires</TableHead>
                  <TableHead>Note</TableHead>
                  <TableHead className="text-right">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {codes.map(c => {
                  const expired = c.expires_at && new Date(c.expires_at) < new Date();
                  return (
                    <TableRow key={c.id}>
                      <TableCell className="font-mono font-semibold">{c.code}</TableCell>
                      <TableCell><Badge variant="outline">{c.role}</Badge></TableCell>
                      <TableCell>{ownerLabel(c.owner_id)}</TableCell>
                      <TableCell>
                        {c.redeemed_at ? (
                          <Badge variant="secondary">Used by {c.redeemed_email}</Badge>
                        ) : expired ? (
                          <Badge variant="destructive">Expired</Badge>
                        ) : (
                          <Badge>Active</Badge>
                        )}
                      </TableCell>
                      <TableCell>{c.expires_at ? format(new Date(c.expires_at), "MMM d, yyyy h:mm a") : "—"}</TableCell>
                      <TableCell className="max-w-xs truncate">{c.note || "—"}</TableCell>
                      <TableCell className="text-right space-x-1">
                        <Button size="sm" variant="ghost" onClick={() => copyCode(c.code)} title="Copy code">
                          <Copy className="h-4 w-4" />
                        </Button>
                        <Button size="sm" variant="ghost" onClick={() => copyLink(c.code)} title="Copy link">
                          <LinkIcon className="h-4 w-4" />
                        </Button>
                        <Button size="sm" variant="ghost" onClick={() => emailCode(c)} title="Email registration link" disabled={!!c.redeemed_at}>
                          <Mail className="h-4 w-4" />
                        </Button>
                        <Button size="sm" variant="ghost" onClick={() => handleDelete(c.id)} title="Delete">
                          <Trash2 className="h-4 w-4" />
                        </Button>
                      </TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          )}
        </CardContent>
      </Card>
    </div>
  );
}

function OwnerCombobox({
  owners,
  value,
  onChange,
}: {
  owners: OwnerOption[];
  value: string;
  onChange: (v: string) => void;
}) {
  const [open, setOpen] = useState(false);
  const selected = value !== "none" ? owners.find((o) => o.id === value) : null;
  const label = selected
    ? `${selected.first_name || ""} ${selected.last_name || ""}`.trim() || selected.email || "Unnamed"
    : "None";
  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          type="button"
          variant="outline"
          role="combobox"
          aria-expanded={open}
          className="w-full justify-between font-normal"
        >
          <span className="truncate">{label}</span>
          <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
        </Button>
      </PopoverTrigger>
      <PopoverContent className="w-[--radix-popover-trigger-width] p-0" align="start">
        <Command
          filter={(itemValue, search) => {
            return itemValue.toLowerCase().includes(search.toLowerCase()) ? 1 : 0;
          }}
        >
          <CommandInput placeholder="Search owners by name or email..." />
          <CommandList>
            <CommandEmpty>No owners found.</CommandEmpty>
            <CommandGroup>
              <CommandItem
                value="none"
                onSelect={() => {
                  onChange("none");
                  setOpen(false);
                }}
              >
                <Check className={cn("mr-2 h-4 w-4", value === "none" ? "opacity-100" : "opacity-0")} />
                None
              </CommandItem>
              {owners.map((o) => {
                const name = `${o.first_name || ""} ${o.last_name || ""}`.trim() || "Unnamed";
                const display = o.email ? `${name} (${o.email})` : name;
                return (
                  <CommandItem
                    key={o.id}
                    value={`${display} ${o.id}`}
                    onSelect={() => {
                      onChange(o.id);
                      setOpen(false);
                    }}
                  >
                    <Check className={cn("mr-2 h-4 w-4", value === o.id ? "opacity-100" : "opacity-0")} />
                    {display}
                  </CommandItem>
                );
              })}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}
