"use client"

import { InviteCard } from "@/components/cards/InviteCard";
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";
import { Command, CommandItem } from "@/components/ui/command";
import { Input } from "@/components/ui/input";
import { Popover, PopoverTrigger, PopoverContent } from "@/components/ui/popover";
import { toast } from "@/components/ui/use-toast";
import { bulkDeleteInvites } from "@/lib/actions";
import { ChannelInvite } from "@/lib/db";
import { ChevronsUpDown } from "lucide-react";
import { useMemo, useState } from "react";
import { Channel, Server, User } from "revolt-api";

export default function ServerInviteList({ server, invites, channels, users }: {
  server: Server,
  invites: ChannelInvite[],
  channels?: Channel[],
  users?: User[],
}) {
  const [selectVanityOnly, setSelectVanityOnly] = useState(false);
  const [selectChannel, setSelectChannel] = useState(false);
  const [selectUser, setSelectUser] = useState(false);
  const [vanityFilter, setVanityFilter] = useState<boolean | null>(null);
  const [channelFilter, setChannelFilter] = useState("");
  const [userFilter, setUserFilter] = useState("");
  const [deletedInvites, setDeletedInvites] = useState<string[]>([]);
  
  const filteredInvites = useMemo(() => {
    return invites
      ?.filter(invite => !deletedInvites.includes(invite._id))
      ?.filter(invite => vanityFilter === true ? invite.vanity : vanityFilter === false ? !invite.vanity : true)
      ?.filter(invite => channelFilter ? invite.channel == channelFilter : true)
      ?.filter(invite => userFilter ? invite.creator == userFilter : true)
      ?.reverse();
  }, [vanityFilter, channelFilter, userFilter, invites, deletedInvites]);

  return (
    <div>
      <div className="flex gap-2">
        <Popover open={selectVanityOnly} onOpenChange={setSelectVanityOnly}>
          <PopoverTrigger asChild>
            <Button
              variant="outline"
              role="combobox"
              aria-expanded={selectVanityOnly}
              className="flex-1 justify-between"
            >
              {vanityFilter === true ? "Vanity" : vanityFilter === false ? "Not vanity" : "All"}
              <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
            </Button>
          </PopoverTrigger>
          <PopoverContent className="w-[200px] p-0">
            <Command>
              {[
                { value: null, label: "All" },
                { value: true, label: "Vanity" },
                { value: false, label: "Not vanity" },
              ].map((option) => (
                <CommandItem
                  key={String(option.value)}
                  onSelect={async () => {
                    setSelectVanityOnly(false);
                    setVanityFilter(option.value);
                  }}
                >{option.label}</CommandItem>
              ))}
            </Command>
          </PopoverContent>
        </Popover>

        <Popover open={selectChannel} onOpenChange={setSelectChannel}>
          <PopoverTrigger asChild>
            <Button
              variant="outline"
              role="combobox"
              aria-expanded={selectChannel}
              className="flex-1 justify-between"
            >
              {channelFilter
                ? '#' + (channels?.find(c => c._id == channelFilter) as any)?.name
                : "Select channel"}
              <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
            </Button>
          </PopoverTrigger>
          <PopoverContent className="w-[200px] p-0">
            <Command>
              <CommandItem onSelect={async () => {
                    setSelectChannel(false);
                    setChannelFilter("");
                  }}
                >All channels</CommandItem>
              {channels?.map((channel) => (
                <CommandItem
                  key={String(channel._id)}
                  onSelect={async () => {
                    setSelectChannel(false);
                    setChannelFilter(channel._id);
                  }}
                >{'#' + (channel as any).name}</CommandItem>
              ))}
            </Command>
          </PopoverContent>
        </Popover>

        <Popover open={selectUser} onOpenChange={setSelectUser}>
          <PopoverTrigger asChild>
            <Button
              variant="outline"
              role="combobox"
              aria-expanded={selectUser}
              className="flex-1 justify-between"
            >
              {userFilter
                ? `${users?.find(c => c._id == userFilter)?.username}#${users?.find(c => c._id == userFilter)?.discriminator}`
                : "Select user"}
              <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
            </Button>
          </PopoverTrigger>
          <PopoverContent className="w-[200px] p-0">
            <Command>
            <CommandItem onSelect={async () => {
                    setSelectUser(false);
                    setUserFilter("");
                  }}
                >All users</CommandItem>
              {users?.map((user) => (
                <CommandItem
                  key={String(user._id)}
                  onSelect={async () => {
                    setSelectUser(false);
                    setUserFilter(user._id);
                  }}
                >{user.username}#{user.discriminator}</CommandItem>
              ))}
            </Command>
          </PopoverContent>
        </Popover>

        <AlertDialog>
            <AlertDialogTrigger asChild>
                <Button disabled={!filteredInvites.length}>Bulk delete</Button>
            </AlertDialogTrigger>
            <AlertDialogContent>
                <AlertDialogHeader>
                    <AlertDialogTitle>
                        Bulk delete invites
                    </AlertDialogTitle>
                </AlertDialogHeader>
                <AlertDialogDescription>
                    This will delete all invites that match your filter options.
                    <br />
                    <b>{filteredInvites.length}</b> invite{filteredInvites.length == 1 ? '' : 's'} will be deleted.
                </AlertDialogDescription>
                <AlertDialogFooter>
                    <AlertDialogAction
                        onClick={async () => {
                            try {
                              await bulkDeleteInvites(filteredInvites.map(i => i._id));
                              setDeletedInvites([...deletedInvites, ...filteredInvites.map(i => i._id)]);
                              toast({ title: "Selected invites have been deleted" });
                            } catch(e) {
                                toast({
                                    title: "Failed to delete invite",
                                    description: String(e),
                                    variant: "destructive",
                                });
                            }
                        }}
                    >Bulk delete</AlertDialogAction>
                    <AlertDialogCancel>Cancel</AlertDialogCancel>
                </AlertDialogFooter>
            </AlertDialogContent>
        </AlertDialog>
      </div>

      {filteredInvites.map(invite => (<InviteCard
        invite={invite}
        channel={channels?.find(c => c._id == invite.channel)}
        user={users?.find(c => c._id == invite.creator)}
        key={invite._id}
      />))}
    </div>
  )
}
