"use client";

import { useState } from "react";
import { Button } from "../../ui/button";
import { useToast } from "../../ui/use-toast";
import type { Account } from "@/lib/db";
import { User } from "revolt-api";
import {
  cancelAccountDeletion,
  changeAccountEmail,
  deleteMFARecoveryCodes,
  disableAccount,
  disableMFA,
  queueAccountDeletion,
  restoreAccount,
  verifyAccountEmail,
} from "@/lib/actions";
import dayjs from "dayjs";

import relativeTime from "dayjs/plugin/relativeTime";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "../../ui/alert-dialog";
import { AlertDialogDescription } from "@radix-ui/react-alert-dialog";
import { Input } from "@/components/ui/input";
dayjs.extend(relativeTime);

export function AccountActions({
  account,
  user,
}: {
  account: Account;
  user?: User;
}) {
  const { toast } = useToast();

  const [accountDraft, setAccountDraft] = useState(account);
  const [emailDraft, setEmailDraft] = useState("");

  return (
    <div className="flex gap-2">
      <AlertDialog>
        <AlertDialogTrigger asChild>
          <Button className="flex-1">
            Change Email
          </Button>
        </AlertDialogTrigger>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>
              Update account email
            </AlertDialogTitle>
            <AlertDialogDescription>
              <Input
                placeholder={account.email}
                onChange={(e) => setEmailDraft(e.currentTarget.value)}
                value={emailDraft}
              />
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              disabled={!/^.+@.+$/.test(emailDraft)}
              onClick={async () => {
                try {
                  await changeAccountEmail(account._id, emailDraft);
                  setEmailDraft("");
                  toast({ title: "Updated email" });
                  window.location.reload();
                } catch (err) {
                  toast({
                    title: "Failed to execute action",
                    description: String(err),
                    variant: "destructive",
                  });
                }
              }}
            >
              Change
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
      
      <AlertDialog>
        <AlertDialogTrigger asChild>
          <Button
            className="flex-1"
            disabled={accountDraft.verification.status == "Verified"}
          >
            {accountDraft.verification.status == "Verified" ? "Email is verified" : "Verify email"}
          </Button>
        </AlertDialogTrigger>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>
              Mark Email as verified
            </AlertDialogTitle>
            <AlertDialogDescription>
              Verification status is currently {accountDraft.verification.status}.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              onClick={async () => {
                try {
                  await verifyAccountEmail(account._id);
                  toast({ title: "Verified email" });
                  setAccountDraft({ ...accountDraft, verification: { status: "Verified" } });
                } catch(e) {
                  toast({
                    title: "Failed to verify",
                    description: String(e),
                    variant: "destructive",
                  })
                }
              }}
            >
              Mark verified
            </AlertDialogAction>
            <AlertDialogAction
              disabled={!(accountDraft.verification.status != "Verified" && accountDraft.verification.token)}
              onClick={() => {
                navigator.clipboard.writeText(`https://app.revolt.chat/login/verify/${(accountDraft.verification as any).token}`);
                toast({ title: "Copied verification link" })
              }}
            >
              Copy link
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
      
      <AlertDialog>
        <AlertDialogTrigger asChild>
          <Button
            className="flex-1"
            disabled={!accountDraft.mfa?.totp_token?.status}
          >
            MFA {accountDraft.mfa?.totp_token?.status.toLowerCase() || "disabled"}
          </Button>
        </AlertDialogTrigger>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>
              Manage MFA
            </AlertDialogTitle>
            <AlertDialogDescription>
            MFA is currently {
              accountDraft.mfa?.totp_token?.status == "Pending"
                ? "pending setup"
                : (accountDraft.mfa?.totp_token?.status.toLowerCase() || "disabled")
            }.
            <br />
            The account has {accountDraft.mfa?.recovery_codes ?? "no"} recovery codes.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogAction
              className="hover:bg-red-800"
              disabled={accountDraft.mfa?.recovery_codes == null}
              onClick={async () => {
                try {
                  await deleteMFARecoveryCodes(account._id);
                  toast({
                    title: "MFA recovery codes cleared",
                  });
                  accountDraft.mfa!.recovery_codes = undefined;
                } catch(e) {
                  toast({
                    title: "Failed to clear recovery codes",
                    description: String(e),
                    variant: "destructive",
                  })
                }
              }}
            >
              Clear recovery codes
            </AlertDialogAction>
            <AlertDialogAction
              className="hover:bg-red-800"
              onClick={async () => {
                try {
                  await disableMFA(account._id);
                  toast({
                    title: "MFA disabled",
                  });
                  accountDraft.mfa!.totp_token = undefined;
                } catch(e) {
                  toast({
                    title: " Failed to disable MFA",
                    description: String(e),
                    variant: "destructive",
                  })
                }
              }}
            >
              Disable MFA
            </AlertDialogAction>
            <AlertDialogCancel>Close</AlertDialogCancel>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      <AlertDialog>
        <AlertDialogTrigger asChild>
          <Button
            className="flex-1"
            disabled={accountDraft.deletion?.status === "Scheduled"}
          >
            {accountDraft.disabled ? "Restore Access" : "Disable"}
          </Button>
        </AlertDialogTrigger>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>
              Are you sure you want to{" "}
              {accountDraft.disabled ? "restore" : "disable"} this account?
            </AlertDialogTitle>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              onClick={async () => {
                try {
                  if (accountDraft.disabled) {
                    await restoreAccount(account._id);
                    setAccountDraft((account) => ({
                      ...account!,
                      disabled: false,
                    }));
                    toast({
                      title: "Restored account",
                    });
                  } else {
                    await disableAccount(account._id);
                    setAccountDraft((account) => ({
                      ...account!,
                      disabled: true,
                    }));
                    toast({
                      title: "Disabled account",
                    });
                  }
                } catch (err) {
                  toast({
                    title: "Failed to execute action",
                    description: String(err),
                    variant: "destructive",
                  });
                }
              }}
            >
              {accountDraft.disabled ? "Restore" : "Disable"}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      <AlertDialog>
        <AlertDialogTrigger asChild>
          <Button
            className="flex-1"
            disabled={
              user?.flags
                ? user?.flags === 2 ||
                  accountDraft.deletion?.status !== "Scheduled"
                : false
            }
          >
            {accountDraft.deletion?.status === "Scheduled"
              ? `Cancel Deletion (${dayjs(
                  (account.deletion as any)?.after
                ).fromNow()})`
              : "Queue Deletion"}
          </Button>
        </AlertDialogTrigger>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>
              Are you sure you want to{" "}
              {accountDraft.deletion?.status === "Scheduled"
                ? "cancel deletion of"
                : "queue deletion for"}{" "}
              this account?
            </AlertDialogTitle>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              onClick={async () => {
                try {
                  if (accountDraft.deletion?.status === "Scheduled") {
                    await cancelAccountDeletion(account._id);
                    setAccountDraft((account) => ({
                      ...account,
                      deletion: null,
                    }));
                    toast({
                      title: "Cancelled account deletion",
                    });
                  } else {
                    const $set = await queueAccountDeletion(account._id);
                    setAccountDraft((account) => ({ ...account!, ...$set }));
                    toast({
                      title: "Queued account for deletion",
                    });
                  }
                } catch (err) {
                  toast({
                    title: "Failed to execute action",
                    description: String(err),
                    variant: "destructive",
                  });
                }
              }}
            >
              {accountDraft.deletion?.status === "Scheduled"
                ? "Unqueue"
                : "Queue"}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}
