import { useState } from "react";
import { Mail, Loader2 } from "lucide-react";
import { useMutation } from "@tanstack/react-query";
import toast from "react-hot-toast";

import { api } from "@/services/api";
import { useAuth } from "@/auth/useAuth";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import {
  Button,
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  Input,
  Label,
} from "@edr/ui-common";

/**
 * Lets the signed-in backoffice user change their own email. Goes through
 * /me/contact/otp + /me/contact rather than the generic (unverified)
 * /auth/update-profile route, so the new address is proven before it's
 * written — see account.controller.ts on the API side.
 */
export function ChangeEmailCard() {
  const { user } = useAuth();
  const sendOtpMutation = useMutation(
    api.account.sendContactOtp.mutationOptions(),
  );
  const updateContactMutation = useMutation(
    api.account.updateContact.mutationOptions(),
  );

  const [open, setOpen] = useState(false);
  const [step, setStep] = useState<"enterEmail" | "enterOtp">("enterEmail");
  const [newEmail, setNewEmail] = useState("");
  const [otp, setOtp] = useState("");
  const [formError, setFormError] = useState("");

  const closeDialog = () => {
    setOpen(false);
    setStep("enterEmail");
    setNewEmail("");
    setOtp("");
    setFormError("");
  };

  const sendOtp = () => {
    setFormError("");
    if (!newEmail.trim()) {
      setFormError("Enter the new email address.");
      return;
    }

    sendOtpMutation.mutate(
      { channel: "email", value: newEmail.trim() },
      {
        onSuccess: (result) => {
          toast.success(`Verification code sent to ${result.sentTo}`);
          setStep("enterOtp");
        },
      },
    );
  };

  const confirmOtp = () => {
    setFormError("");
    if (!otp.trim()) {
      setFormError("Enter the verification code.");
      return;
    }

    updateContactMutation.mutate(
      { channel: "email", value: newEmail.trim(), otp: otp.trim() },
      {
        onSuccess: () => {
          toast.success("Email updated.");
          closeDialog();
          // Refetches the session so the new email shows everywhere — simplest
          // way to refresh the cached user without a dedicated context method.
          window.location.reload();
        },
      },
    );
  };

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center gap-2">
          <Mail className="size-4" />
          Email
        </CardTitle>
        <CardDescription>
          {user?.email ? `Current email: ${user.email}` : "Change your account email."}
        </CardDescription>
      </CardHeader>
      <CardContent>
        <Button variant="outline" size="sm" onClick={() => setOpen(true)}>
          Change email
        </Button>
      </CardContent>

      <Dialog open={open} onOpenChange={(next) => !next && closeDialog()}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>Change email</DialogTitle>
            <DialogDescription>
              {step === "enterEmail"
                ? "We'll send a verification code to the new address."
                : `Enter the code sent to ${newEmail}.`}
            </DialogDescription>
          </DialogHeader>

          {step === "enterEmail" ? (
            <div className="space-y-2">
              <Label htmlFor="newEmail">New email</Label>
              <Input
                id="newEmail"
                type="email"
                value={newEmail}
                onChange={(e) => setNewEmail(e.target.value)}
              />
              {formError && <p className="text-sm text-destructive">{formError}</p>}
            </div>
          ) : (
            <div className="space-y-2">
              <Label htmlFor="otp">Verification code</Label>
              <Input
                id="otp"
                value={otp}
                onChange={(e) => setOtp(e.target.value)}
              />
              {formError && <p className="text-sm text-destructive">{formError}</p>}
            </div>
          )}

          <DialogFooter>
            <Button variant="outline" onClick={closeDialog}>
              Cancel
            </Button>
            {step === "enterEmail" ? (
              <Button disabled={sendOtpMutation.isPending} onClick={sendOtp}>
                {sendOtpMutation.isPending ? (
                  <Loader2 className="size-4 animate-spin" />
                ) : (
                  "Send code"
                )}
              </Button>
            ) : (
              <Button disabled={updateContactMutation.isPending} onClick={confirmOtp}>
                {updateContactMutation.isPending ? (
                  <Loader2 className="size-4 animate-spin" />
                ) : (
                  "Confirm"
                )}
              </Button>
            )}
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </Card>
  );
}
