import { useState, type FormEvent } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { toast } from "@/hooks/use-toast";
import { apiRequest, getQueryFn } from "@/lib/queryClient";
import type { User } from "@shared/schema";

type SessionUser = Pick<User, "id" | "username">;

type AuthPayload = {
  email: string;
  password: string;
};

interface AuthDialogsProps {
  layout?: "desktop" | "mobile";
}

export default function AuthDialogs({ layout = "desktop" }: AuthDialogsProps) {
  const queryClient = useQueryClient();
  const [signupOpen, setSignupOpen] = useState(false);
  const [loginOpen, setLoginOpen] = useState(false);
  const [resetOpen, setResetOpen] = useState(false);
  const [resetStep, setResetStep] = useState<"request" | "confirm">("request");
  const [resetEmail, setResetEmail] = useState("");
  const [resetOtp, setResetOtp] = useState("");
  const [resetPassword, setResetPassword] = useState("");
  const [signupForm, setSignupForm] = useState<AuthPayload>({
    email: "",
    password: "",
  });
  const [loginForm, setLoginForm] = useState<AuthPayload>({
    email: "",
    password: "",
  });

  useQuery<SessionUser | null>({
    queryKey: ["/me"],
    queryFn: getQueryFn<SessionUser | null>({ on401: "returnNull" }),
  });

  const handleAuthSuccess = (
    user: SessionUser,
    action: "signup" | "login",
  ) => {
    queryClient.setQueryData(["/me"], user);
    queryClient.invalidateQueries({ queryKey: ["/broker/status"] });
    toast({
      title: action === "signup" ? "Account created" : "Signed in",
      description:
        action === "signup"
          ? "Your account has been created."
          : `Welcome back ${user.username}`,
    });
    setSignupOpen(false);
    setLoginOpen(false);
  };

  const signupMutation = useMutation<SessionUser, Error, AuthPayload>({
    mutationFn: async (payload) => {
      const res = await apiRequest("POST", "/signup", {
        username: payload.email,
        password: payload.password,
      });
      return res.json();
    },
    onSuccess: (user) => handleAuthSuccess(user, "signup"),
    onError: (err) => {
      toast({
        title: "Signup failed",
        description: err.message,
      });
    },
  });

  const loginMutation = useMutation<SessionUser, Error, AuthPayload>({
    mutationFn: async (payload) => {
      const res = await apiRequest("POST", "/login", payload);
      return res.json();
    },
    onSuccess: (user) => handleAuthSuccess(user, "login"),
    onError: (err) => {
      toast({
        title: "Login failed",
        description: err.message,
      });
    },
  });

  const handleSignup = (event: FormEvent) => {
    event.preventDefault();
    signupMutation.mutate(signupForm);
  };

  const handleLogin = (event: FormEvent) => {
    event.preventDefault();
    loginMutation.mutate(loginForm);
  };

  const resetRequestMutation = useMutation({
    mutationFn: async (email: string) => {
      const res = await apiRequest("POST", "/password-reset/request", { email });
      return res.json();
    },
    onSuccess: () => {
      toast({ title: "OTP sent", description: "Check your email for the 4-digit code." });
      setResetStep("confirm");
    },
    onError: (err: any) => {
      toast({ title: "Failed to send OTP", description: err?.message || "Try again." });
    },
  });

  const resetConfirmMutation = useMutation({
    mutationFn: async () => {
      const res = await apiRequest("POST", "/password-reset/confirm", {
        email: resetEmail.trim(),
        otp: resetOtp.trim(),
        new_password: resetPassword,
      });
      return res.json();
    },
    onSuccess: () => {
      toast({ title: "Password updated", description: "You can log in now." });
      setResetOpen(false);
      setResetStep("request");
      setResetOtp("");
      setResetPassword("");
    },
    onError: (err: any) => {
      toast({ title: "Reset failed", description: err?.message || "Try again." });
    },
  });

  const buttonClass =
    layout === "mobile"
      ? "w-full justify-center"
      : "px-4 rounded-xl min-w-[96px]";

  return (
    <div
      className={
        layout === "mobile"
          ? "flex flex-col gap-3"
          : "flex items-center gap-3"
      }
    >
      <Dialog open={signupOpen} onOpenChange={setSignupOpen}>
        <DialogTrigger asChild>
          <Button variant="outline" className={buttonClass}>
            Sign up
          </Button>
        </DialogTrigger>
        <DialogContent>
          <DialogHeader className="space-y-2">
            <DialogTitle>Create account</DialogTitle>
            <DialogDescription>
              Create an account with your email and a password.
            </DialogDescription>
          </DialogHeader>
          <form className="space-y-4" onSubmit={handleSignup}>
            <div className="space-y-2">
              <Label htmlFor="signup-email">Email</Label>
              <Input
                id="signup-email"
                type="email"
                required
                placeholder="you@example.com"
                value={signupForm.email}
                onChange={(e) =>
                  setSignupForm((prev) => ({ ...prev, email: e.target.value.trim() }))
                }
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="signup-password">Password</Label>
              <Input
                id="signup-password"
                type="password"
                required
                minLength={6}
                value={signupForm.password}
                onChange={(e) =>
                  setSignupForm((prev) => ({ ...prev, password: e.target.value }))
                }
              />
            </div>
            <Button
              type="submit"
              className="w-full"
              disabled={signupMutation.isPending}
            >
              {signupMutation.isPending ? "Creating account..." : "Create account"}
            </Button>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog open={loginOpen} onOpenChange={setLoginOpen}>
        <DialogTrigger asChild>
          <Button className={buttonClass}>Log in</Button>
        </DialogTrigger>
        <DialogContent>
          <DialogHeader className="space-y-2">
            <DialogTitle>Log in</DialogTitle>
            <DialogDescription>
              Enter your email and password to access your account.
            </DialogDescription>
          </DialogHeader>
          <form className="space-y-4" onSubmit={handleLogin}>
            <div className="space-y-2">
              <Label htmlFor="login-email">Email</Label>
              <Input
                id="login-email"
                type="email"
                required
                placeholder="you@example.com"
                value={loginForm.email}
                onChange={(e) =>
                  setLoginForm((prev) => ({ ...prev, email: e.target.value.trim() }))
                }
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="login-password">Password</Label>
              <Input
                id="login-password"
                type="password"
                required
                value={loginForm.password}
                onChange={(e) =>
                  setLoginForm((prev) => ({ ...prev, password: e.target.value }))
                }
              />
            </div>
            <Button
              type="submit"
              className="w-full"
              disabled={loginMutation.isPending}
            >
              {loginMutation.isPending ? "Signing in..." : "Log in"}
            </Button>
            <Button
              type="button"
              variant="ghost"
              className="w-full text-sm"
              onClick={() => {
                setResetEmail(loginForm.email.trim());
                setResetOpen(true);
              }}
            >
              Forgot password?
            </Button>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog open={resetOpen} onOpenChange={setResetOpen}>
        <DialogContent>
          <DialogHeader className="space-y-2">
            <DialogTitle>Reset password</DialogTitle>
            <DialogDescription>
              {resetStep === "request"
                ? "We’ll email you a 4-digit OTP."
                : "Enter the OTP and choose a new password."}
            </DialogDescription>
          </DialogHeader>
          {resetStep === "request" ? (
            <div className="space-y-4">
              <div className="space-y-2">
                <Label htmlFor="reset-email">Email</Label>
                <Input
                  id="reset-email"
                  type="email"
                  required
                  placeholder="you@example.com"
                  value={resetEmail}
                  onChange={(e) => setResetEmail(e.target.value.trim())}
                />
              </div>
              <Button
                className="w-full"
                disabled={resetRequestMutation.isPending || !resetEmail.trim()}
                onClick={() => resetRequestMutation.mutate(resetEmail.trim())}
              >
                {resetRequestMutation.isPending ? "Sending..." : "Send OTP"}
              </Button>
            </div>
          ) : (
            <div className="space-y-4">
              <div className="space-y-2">
                <Label htmlFor="reset-otp">OTP</Label>
                <Input
                  id="reset-otp"
                  inputMode="numeric"
                  maxLength={4}
                  value={resetOtp}
                  onChange={(e) => setResetOtp(e.target.value)}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="reset-new-password">New password</Label>
                <Input
                  id="reset-new-password"
                  type="password"
                  minLength={6}
                  value={resetPassword}
                  onChange={(e) => setResetPassword(e.target.value)}
                />
              </div>
              <Button
                className="w-full"
                disabled={
                  resetConfirmMutation.isPending ||
                  !resetEmail.trim() ||
                  !resetOtp.trim() ||
                  !resetPassword
                }
                onClick={() => resetConfirmMutation.mutate()}
              >
                {resetConfirmMutation.isPending ? "Updating..." : "Update password"}
              </Button>
            </div>
          )}
        </DialogContent>
      </Dialog>
    </div>
  );
}
