import React, { useEffect, useState } from "react";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  AlertTriangle,
  Copy,
  Download,
  Filter,
  MoreHorizontal,
  Plus,
  Search,
  Send,
} from "lucide-react";
import { useGuests } from "@/context/guest-context";
import {
  EventResponse,
  GuestCreate,
  GuestRead,
  GuestStatus,
  GuestUpdate,
} from "@/client/types.gen";
import { Textarea } from "@/components/ui/textarea";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { toast } from "sonner";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { useAuth } from "@/context/auth-context";
import { generateInviteLink } from "@/lib/utils";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { StickyNote, Utensils } from "lucide-react";

// Helper to generate a random invitation code
const generateInvitationCode = (fullName: string): string => {
  const namePart = fullName
    .replace(/[^A-Za-z]/g, "")
    .substring(0, 6)
    .toUpperCase();
  const randomPart = Math.floor(Math.random() * 1000)
    .toString()
    .padStart(5, "0");
  return `${namePart}${randomPart}`;
};

type GuestListTableProps = {
  event: EventResponse;
};

const GuestListTable = ({ event }: GuestListTableProps) => {
  // State
  const [addGuestOpen, setAddGuestOpen] = useState(false);
  const [editGuestOpen, setEditGuestOpen] = useState(false);
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");
  const [currentGuest, setCurrentGuest] = useState<GuestRead | null>(null);

  // Form state
  const initialState = {
    full_name: "",
    email: "",
    phone: "",
    max_additional_guests: 0,
    dietary_restrictions: "",
    notes: "",
    can_bring_guests: true,
  };
  const [formData, setFormData] =
    useState<Partial<GuestCreate & GuestUpdate>>(initialState);

  // Access guest context
  const {
    guests,
    isLoadingGuests,
    error,
    createGuest,
    updateGuest,
    deleteGuest,
    refetchGuests,
    currentGuestId,
    setCurrentGuestId,
  } = useGuests();
  const { user } = useAuth();

  // Filter guests by search query
  const filteredGuests =
    guests?.filter(
      (guest) =>
        guest.full_name.toLowerCase().includes(searchQuery.toLowerCase()) ||
        (guest.email?.toLowerCase() || "").includes(
          searchQuery.toLowerCase(),
        ) ||
        guest.invitation_code.toLowerCase().includes(searchQuery.toLowerCase()),
    ) || [];

  // Handle form input changes
  const handleInputChange = (
    e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
  ) => {
    const { name, value } = e.target;
    setFormData((prev) => ({ ...prev, [name]: value }));
  };

  // Handle select changes
  const handleSelectChange = (
    name: string,
    value: string | number | boolean,
  ) => {
    setFormData((prev) => ({ ...prev, [name]: value }));
  };

  // Handle add guest form submission
  const handleAddGuest = async () => {
    try {
      if (!formData.full_name) {
        toast.error("Full name is required");
        return;
      }

      // Get the event ID from the first guest or use a default
      // In a real implementation, you would probably pass this as a prop
      const eventId = event.id; // This should be replaced with the actual event ID

      // Get the current user ID
      // In a real implementation, you would get this from an auth context
      const invitedBy = user?.id || "admin"; // This should be replaced with the current user ID

      const newGuest: GuestCreate = {
        event_id: eventId,
        invited_by: invitedBy,
        full_name: formData.full_name || "",
        email: formData.email || null,
        phone: formData.phone || null,
        max_additional_guests:
          typeof formData.max_additional_guests === "number"
            ? formData.max_additional_guests
            : 0,
        dietary_restrictions: formData.dietary_restrictions || null,
        notes: formData.notes || null,
        can_bring_guests: formData.can_bring_guests || true,
        invitation_code: generateInvitationCode(formData.full_name || ""),
      };

      await createGuest(newGuest);

      toast.success("Guest added successfully");

      setAddGuestOpen(false);
      setFormData(initialState);
    } catch (error) {
      console.error("Error adding guest:", error);
      toast.error("Failed to add guest");
    }
  };

  // Handle edit guest
  const handleEditGuest = async () => {
    try {
      if (!currentGuest) return;

      const updatedGuest: GuestUpdate = {
        full_name: formData.full_name || null,
        email: formData.email || null,
        phone: formData.phone || null,
        max_additional_guests:
          typeof formData.max_additional_guests === "number"
            ? formData.max_additional_guests
            : null,
        dietary_restrictions: formData.dietary_restrictions || null,
        notes: formData.notes || null,
        can_bring_guests: formData.can_bring_guests || null,
      };

      await updateGuest(currentGuest.id, updatedGuest);

      toast.success("Guest updated successfully");

      setEditGuestOpen(false);
    } catch (error) {
      console.error("Error updating guest:", error);
      toast.error("Failed to update guest");
    }
  };

  // Handle delete guest
  const handleDeleteGuest = async () => {
    try {
      if (!currentGuest) return;

      await deleteGuest(currentGuest.id);
      setFormData(initialState);
      setCurrentGuest(null);
      toast.success("Guest deleted successfully");

      setDeleteDialogOpen(false);
    } catch (error) {
      console.error("Error deleting guest:", error);
      toast.error("Failed to delete guest");
    }
  };

  // Prepare to edit a guest
  const prepareEditGuest = (guest: GuestRead) => {
    setCurrentGuest(guest);
    setFormData({
      full_name: guest.full_name,
      email: guest.email || "",
      phone: guest.phone || "",
      max_additional_guests: guest.max_additional_guests || 0,
      dietary_restrictions: guest.dietary_restrictions || "",
      notes: guest.notes || "",
      can_bring_guests: guest.can_bring_guests || false,
    });
    setEditGuestOpen(true);
  };

  // Prepare to delete a guest
  const prepareDeleteGuest = (guest: GuestRead) => {
    setCurrentGuest(guest);
    setDeleteDialogOpen(true);
  };

  // Helper to get status badge
  const getStatusBadge = (status: GuestStatus) => {
    const statusStyles: Record<GuestStatus, string> = {
      [GuestStatus.INVITED]: "bg-blue-100 text-blue-800",
      [GuestStatus.PENDING]: "bg-yellow-100 text-yellow-800",
      [GuestStatus.CONFIRMED]: "bg-green-100 text-green-800",
      [GuestStatus.DECLINED]: "bg-red-100 text-red-800",
      [GuestStatus.WAITLISTED]: "bg-purple-100 text-purple-800",
      [GuestStatus.CANCELLED]: "bg-gray-100 text-gray-800",
    };

    return (
      <Badge className={statusStyles[status]}>{status.toUpperCase()}</Badge>
    );
  };

  // Copy invitation code to clipboard
  const copyToClipboard = (text: string, message: string) => {
    navigator.clipboard.writeText(text);
    toast(message);
  };

  // Export guest list to CSV
  const exportToCSV = () => {
    if (!guests || guests.length === 0) return;

    const headers = [
      "Name",
      "Email",
      "Phone",
      "Invitation Code",
      "Status",
      "Additional Guests",
    ];
    const csvContent = [
      headers.join(","),
      ...guests.map((guest) =>
        [
          `"${guest.full_name}"`,
          `"${guest.email || ""}"`,
          `"${guest.phone || ""}"`,
          `"${guest.invitation_code}"`,
          `"${guest.status}"`,
          guest.max_additional_guests || 0,
        ].join(","),
      ),
    ].join("\n");

    const blob = new Blob([csvContent], { type: "text/csv" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.setAttribute("href", url);
    a.setAttribute("download", "guest-list.csv");
    a.click();
  };

  // Send invitations (stub - in a real app, this would integrate with your email service)
  const sendInvitations = () => {
    toast("Sending Invitations", {
      description:
        "This feature would send invitations to all uninvited guests",
      action: {
        label: "Cancel",
        onClick: () => console.log("Cancelled sending invitations"),
      },
    });
  };
  useEffect(() => {
    // When add dialog opens, always reset to initial state
    if (addGuestOpen) {
      setFormData(initialState);
      setCurrentGuest(null);
    }
    // When edit dialog opens, form data should reflect the current guest
    else if (editGuestOpen && currentGuest) {
      setFormData({
        full_name: currentGuest.full_name,
        email: currentGuest.email || "",
        phone: currentGuest.phone || "",
        max_additional_guests: currentGuest.max_additional_guests || 0,
        dietary_restrictions: currentGuest.dietary_restrictions || "",
        notes: currentGuest.notes || "",
        can_bring_guests: currentGuest.can_bring_guests || false,
      });
    }
  }, [addGuestOpen, editGuestOpen, currentGuest]);

  return (
    <div className="space-y-4 w-full">
      {error && (
        <div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative flex items-center">
          <AlertTriangle className="h-5 w-5 mr-2" />
          <span>Error loading guests: {error.message}</span>
        </div>
      )}

      <div className="flex items-center justify-between">
        <h2 className="text-2xl font-bold">Guest List</h2>
        <div className="flex gap-2">
          <Button variant="outline" size="sm" onClick={exportToCSV}>
            <Download className="mr-2 h-4 w-4" /> Export
          </Button>
          <Dialog open={addGuestOpen} onOpenChange={setAddGuestOpen}>
            <DialogTrigger asChild>
              <Button className="bg-blue-600 hover:bg-blue-700">
                <Plus className="mr-2 h-4 w-4" /> Add Guest
              </Button>
            </DialogTrigger>
            <DialogContent className="sm:max-w-md">
              <DialogHeader>
                <DialogTitle>Add New Guest</DialogTitle>
              </DialogHeader>
              <div className="grid gap-4 py-4">
                <div className="grid grid-cols-4 items-center gap-4">
                  <Label htmlFor="full_name" className="text-right">
                    Full Name <span className="text-red-500">*</span>
                  </Label>
                  <Input
                    id="full_name"
                    name="full_name"
                    value={formData.full_name || ""}
                    onChange={handleInputChange}
                    className="col-span-3"
                    required
                  />
                </div>
                <div className="grid grid-cols-4 items-center gap-4">
                  <Label htmlFor="email" className="text-right">
                    Email
                  </Label>
                  <Input
                    id="email"
                    name="email"
                    type="email"
                    value={formData.email || ""}
                    onChange={handleInputChange}
                    className="col-span-3"
                  />
                </div>
                <div className="grid grid-cols-4 items-center gap-4">
                  <Label htmlFor="phone" className="text-right">
                    Phone
                  </Label>
                  <Input
                    id="phone"
                    name="phone"
                    value={formData.phone || ""}
                    onChange={handleInputChange}
                    className="col-span-3"
                  />
                </div>
                <div className="grid grid-cols-4 items-center gap-4">
                  <Label htmlFor="max_additional_guests" className="text-right">
                    Additional Guests
                  </Label>
                  <Input
                    id="max_additional_guests"
                    name="max_additional_guests"
                    type="number"
                    min="0"
                    value={formData.max_additional_guests || 0}
                    onChange={handleInputChange}
                    className="col-span-3"
                  />
                </div>
                <div className="grid grid-cols-4 items-start gap-4">
                  <Label
                    htmlFor="dietary_restrictions"
                    className="text-right pt-2"
                  >
                    Dietary Restrictions
                  </Label>
                  <Textarea
                    id="dietary_restrictions"
                    name="dietary_restrictions"
                    value={formData.dietary_restrictions || ""}
                    onChange={handleInputChange}
                    className="col-span-3"
                    rows={2}
                  />
                </div>
                <div className="grid grid-cols-4 items-start gap-4">
                  <Label htmlFor="notes" className="text-right pt-2">
                    Notes
                  </Label>
                  <Textarea
                    id="notes"
                    name="notes"
                    value={formData.notes || ""}
                    onChange={handleInputChange}
                    className="col-span-3"
                    rows={2}
                  />
                </div>
                <div className="grid grid-cols-4 items-center gap-4">
                  <Label htmlFor="can_bring_guests" className="text-right">
                    Can Bring Guests
                  </Label>
                  <Select
                    value={
                      formData.can_bring_guests !== undefined
                        ? String(formData.can_bring_guests)
                        : "true"
                    }
                    onValueChange={(value: string) =>
                      handleSelectChange("can_bring_guests", value === "true")
                    }
                  >
                    <SelectTrigger className="col-span-3">
                      <SelectValue placeholder="Select option" />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="true">Yes</SelectItem>
                      <SelectItem value="false">No</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
              </div>
              <DialogFooter>
                <Button
                  variant="outline"
                  onClick={() => setAddGuestOpen(false)}
                >
                  Cancel
                </Button>
                <Button
                  className="bg-blue-600 hover:bg-blue-700"
                  onClick={handleAddGuest}
                >
                  Add Guest
                </Button>
              </DialogFooter>
            </DialogContent>
          </Dialog>
        </div>
      </div>

      <div className="flex justify-between items-center">
        <div className="relative w-64">
          <Search className="absolute left-2 top-2.5 h-4 w-4 text-gray-500" />
          <Input
            placeholder="Search guests..."
            className="pl-8"
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
          />
        </div>
        <div className="flex gap-2">
          <Button variant="outline" size="sm">
            <Filter className="mr-2 h-4 w-4" /> Filter
          </Button>
          <Button variant="outline" size="sm" onClick={sendInvitations}>
            <Send className="mr-2 h-4 w-4" /> Send Invites
          </Button>
        </div>
      </div>

      <div className="rounded-md border">
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead>Name</TableHead>
              <TableHead>Email</TableHead>
              <TableHead>Phone</TableHead>
              <TableHead>Invitation Code</TableHead>
              <TableHead>Status</TableHead>
              <TableHead>Add. Guests</TableHead>
              <TableHead>Diet Restr.</TableHead>
              <TableHead>Notes</TableHead>
              <TableHead className="text-right">Actions</TableHead>
            </TableRow>
          </TableHeader>

          <TableBody>
            {isLoadingGuests ? (
              <TableRow>
                <TableCell colSpan={7} className="text-center py-8">
                  Loading guests...
                </TableCell>
              </TableRow>
            ) : filteredGuests.length === 0 ? (
              <TableRow>
                <TableCell colSpan={7} className="text-center py-8">
                  No guests found. Add your first guest!
                </TableCell>
              </TableRow>
            ) : (
              filteredGuests.map((guest) => (
                <TableRow key={guest.id}>
                  <TableCell className="font-medium">
                    {guest.full_name}
                  </TableCell>
                  <TableCell>{guest.email || "-"}</TableCell>
                  <TableCell>{guest.phone || "-"}</TableCell>
                  <TableCell>
                    <div className="flex items-center gap-1">
                      {guest.invitation_code}
                      <Button
                        variant="ghost"
                        size="icon"
                        className="h-6 w-6"
                        onClick={() =>
                          copyToClipboard(
                            guest.invitation_code,
                            "Invitation code copied to clipboard",
                          )
                        }
                      >
                        <Copy className="h-3 w-3" />
                      </Button>
                    </div>
                  </TableCell>
                  <TableCell>{getStatusBadge(guest.status)}</TableCell>
                  <TableCell>{guest.actual_additional_guests || 0}</TableCell>

                  {/* Dietary Restrictions Column */}
                  <TableCell>
                    {guest.dietary_restrictions &&
                    guest.dietary_restrictions.length > 0 ? (
                      <Popover>
                        <PopoverTrigger asChild>
                          <Button
                            variant="ghost"
                            size="icon"
                            className="h-6 w-6"
                          >
                            <Utensils className="h-4 w-4 text-green-600 cursor-pointer" />
                          </Button>
                        </PopoverTrigger>
                        <PopoverContent className="max-w-xs">
                          <p className="text-sm">
                            {guest.dietary_restrictions}
                          </p>
                        </PopoverContent>
                      </Popover>
                    ) : (
                      "-"
                    )}
                  </TableCell>

                  {/* Notes Column */}
                  <TableCell>
                    {guest.notes && guest.notes.length > 0 ? (
                      <Popover>
                        <PopoverTrigger asChild>
                          <Button
                            variant="ghost"
                            size="icon"
                            className="h-6 w-6"
                          >
                            <StickyNote className="h-4 w-4 text-blue-600 cursor-pointer" />
                          </Button>
                        </PopoverTrigger>
                        <PopoverContent className="max-w-xs">
                          <p className="text-sm">{guest.notes}</p>
                        </PopoverContent>
                      </Popover>
                    ) : (
                      "-"
                    )}
                  </TableCell>

                  <TableCell className="text-right">
                    <DropdownMenu>
                      <DropdownMenuTrigger asChild>
                        <Button variant="ghost" size="icon" className="h-8 w-8">
                          <MoreHorizontal className="h-4 w-4" />
                        </Button>
                      </DropdownMenuTrigger>
                      <DropdownMenuContent align="end">
                        <DropdownMenuItem
                          onClick={() => prepareEditGuest(guest)}
                        >
                          Edit
                        </DropdownMenuItem>
                        <DropdownMenuItem
                          onClick={() =>
                            copyToClipboard(
                              guest.invitation_code,
                              "Invitation code copied to clipboard",
                            )
                          }
                        >
                          Copy Invitation Code
                        </DropdownMenuItem>
                        <DropdownMenuItem
                          onClick={() =>
                            copyToClipboard(
                              generateInviteLink(
                                event.slug,
                                guest.invitation_code,
                              ),
                              "Invitation link copied to clipboard",
                            )
                          }
                        >
                          Copy Invitation Link
                        </DropdownMenuItem>
                        <DropdownMenuItem>Resend Invitation</DropdownMenuItem>
                        <DropdownMenuSeparator />
                        <DropdownMenuItem
                          className="text-red-600"
                          onClick={() => prepareDeleteGuest(guest)}
                        >
                          Delete
                        </DropdownMenuItem>
                      </DropdownMenuContent>
                    </DropdownMenu>
                  </TableCell>
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>
      </div>

      <div className="flex justify-between text-sm text-gray-500">
        <div>
          Showing {filteredGuests.length} of {guests?.length || 0} guests
        </div>
        <div>
          Total Confirmed:{" "}
          {guests?.filter((g) => g.status === GuestStatus.CONFIRMED).length ||
            0}{" "}
          | Total Additional Guests:{" "}
          {guests?.reduce(
            (acc, g) => acc + (g.max_additional_guests || 0),
            0,
          ) || 0}
        </div>
      </div>

      {/* Edit Guest Dialog */}
      <Dialog open={editGuestOpen} onOpenChange={setEditGuestOpen}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>Edit Guest</DialogTitle>
          </DialogHeader>
          <div className="grid gap-4 py-4">
            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="edit_full_name" className="text-right">
                Full Name <span className="text-red-500">*</span>
              </Label>
              <Input
                id="edit_full_name"
                name="full_name"
                value={formData.full_name || ""}
                onChange={handleInputChange}
                className="col-span-3"
                required
              />
            </div>
            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="edit_email" className="text-right">
                Email
              </Label>
              <Input
                id="edit_email"
                name="email"
                type="email"
                value={formData.email || ""}
                onChange={handleInputChange}
                className="col-span-3"
              />
            </div>
            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="edit_phone" className="text-right">
                Phone
              </Label>
              <Input
                id="edit_phone"
                name="phone"
                value={formData.phone || ""}
                onChange={handleInputChange}
                className="col-span-3"
              />
            </div>
            <div className="grid grid-cols-4 items-center gap-4">
              <Label
                htmlFor="edit_max_additional_guests"
                className="text-right"
              >
                Additional Guests
              </Label>
              <Input
                id="edit_max_additional_guests"
                name="max_additional_guests"
                type="number"
                min="0"
                value={formData.max_additional_guests || 0}
                onChange={handleInputChange}
                className="col-span-3"
              />
            </div>
            <div className="grid grid-cols-4 items-start gap-4">
              <Label
                htmlFor="edit_dietary_restrictions"
                className="text-right pt-2"
              >
                Dietary Restrictions
              </Label>
              <Textarea
                id="edit_dietary_restrictions"
                name="dietary_restrictions"
                value={formData.dietary_restrictions || ""}
                onChange={handleInputChange}
                className="col-span-3"
                rows={2}
              />
            </div>
            <div className="grid grid-cols-4 items-start gap-4">
              <Label htmlFor="edit_notes" className="text-right pt-2">
                Notes
              </Label>
              <Textarea
                id="edit_notes"
                name="notes"
                value={formData.notes || ""}
                onChange={handleInputChange}
                className="col-span-3"
                rows={2}
              />
            </div>
            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="edit_can_bring_guests" className="text-right">
                Can Bring Guests
              </Label>
              <Select
                value={formData.can_bring_guests ? "true" : "false"}
                onValueChange={(value) =>
                  handleSelectChange("can_bring_guests", value === "true")
                }
              >
                <SelectTrigger className="col-span-3">
                  <SelectValue placeholder="Select option" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="true">Yes</SelectItem>
                  <SelectItem value="false">No</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setEditGuestOpen(false)}>
              Cancel
            </Button>
            <Button
              className="bg-blue-600 hover:bg-blue-700"
              onClick={handleEditGuest}
            >
              Save Changes
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Delete Confirmation Dialog */}
      <AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Are you sure?</AlertDialogTitle>
            <AlertDialogDescription>
              This will permanently delete the guest "{currentGuest?.full_name}
              ". This action cannot be undone.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              className="bg-red-600 hover:bg-red-700 text-white"
              onClick={handleDeleteGuest}
            >
              Delete
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
};

export default GuestListTable;
