import { useEffect, useState } from 'react';
import type { LoginPayload } from '@/types';
import type { Location } from 'react-router-dom';
import { Link, Navigate, useLocation, useNavigate } from 'react-router-dom';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { LoaderCircle, LockKeyhole, Mail, UserCircle2 } from 'lucide-react';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { useAuth } from '@/hooks/useAuth';
import { lookupRecoveryUsernameByEmail, resetPasswordByEmail } from '@/services/authService';

const loginSchema = z.object({
  username: z.string().min(1, '请输入用户名'),
  password: z.string().min(1, '请输入密码'),
});

type LoginFormValues = z.infer<typeof loginSchema>;

const forgotPasswordSchema = z
  .object({
    email: z.string().min(1, '请输入邮箱').email('请输入有效的邮箱地址'),
    newPassword: z.string().min(6, '新密码至少需要 6 位'),
    confirmPassword: z.string().min(1, '请再次输入新密码'),
  })
  .refine(values => values.newPassword === values.confirmPassword, {
    message: '两次输入的新密码不一致',
    path: ['confirmPassword'],
  });

type ForgotPasswordFormValues = z.infer<typeof forgotPasswordSchema>;

function getRedirectPath(location: ReturnType<typeof useLocation>) {
  const navigationState = location.state as { from?: Location } | null;
  const from = navigationState?.from;

  if (!from) {
    return '/';
  }

  return `${from.pathname}${from.search}${from.hash}`;
}

export default function Login() {
  const location = useLocation();
  const navigate = useNavigate();
  const { isAuthenticated, isBootstrapping, login } = useAuth();
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [forgotPasswordOpen, setForgotPasswordOpen] = useState(false);
  const redirectPath = getRedirectPath(location);
  const form = useForm<LoginFormValues>({
    resolver: zodResolver(loginSchema),
    defaultValues: {
      username: '',
      password: '',
    },
  });

  if (!isBootstrapping && isAuthenticated) {
    return <Navigate to={redirectPath} replace />;
  }

  async function handleSubmit(values: LoginFormValues) {
    setIsSubmitting(true);

    try {
      await login(values as LoginPayload);
      toast.success('登录成功');
      navigate(redirectPath, { replace: true });
    } catch (error) {
      toast.error(error instanceof Error ? error.message : '登录失败');
    } finally {
      setIsSubmitting(false);
    }
  }

  return (
    <div className="flex min-h-screen items-center justify-center bg-[#f8fafc] px-6 py-10">
      <Card className="w-full max-w-[420px] rounded-[24px] border border-[#dbe7fb] bg-white p-10 shadow-[0_28px_60px_-36px_rgba(37,99,235,0.18)] sm:w-[420px]">
        <CardHeader className="space-y-4 px-0 pb-8 pt-0 text-center">
          <div className="mx-auto flex h-14 w-14 items-center justify-center rounded-2xl bg-[linear-gradient(135deg,#2563eb_0%,#3b82f6_55%,#60a5fa_100%)] text-white shadow-[0_18px_32px_-20px_rgba(37,99,235,0.55)] transition-all duration-300 hover:-translate-y-0.5 hover:shadow-[0_22px_38px_-22px_rgba(37,99,235,0.62)]">
            <LockKeyhole className="h-6 w-6" />
          </div>
          <CardTitle className="text-xl font-bold tracking-[0.02em] text-[#1d4ed8]">登录系统</CardTitle>
        </CardHeader>

        <CardContent className="space-y-6 px-0 pb-0">
          <Form {...form}>
            <form className="space-y-5" onSubmit={form.handleSubmit(handleSubmit)}>
              <FormField
                control={form.control}
                name="username"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel className="text-slate-700">用户名</FormLabel>
                    <FormControl>
                      <div className="relative">
                        <UserCircle2 className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400" />
                        <Input
                          className="h-11 rounded-xl border-gray-200 bg-white pl-10 text-slate-800 transition-all duration-200 hover:border-[#bfdbfe] hover:shadow-[0_10px_18px_-16px_rgba(37,99,235,0.35)] focus-visible:border-[#3b82f6] focus-visible:ring-1 focus-visible:ring-[#93c5fd]/60"
                          placeholder="请输入用户名"
                          autoComplete="username"
                          {...field}
                        />
                      </div>
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />

              <FormField
                control={form.control}
                name="password"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel className="text-slate-700">密码</FormLabel>
                    <FormControl>
                      <div className="relative">
                        <LockKeyhole className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400" />
                        <Input
                          className="h-11 rounded-xl border-gray-200 bg-white pl-10 text-slate-800 transition-all duration-200 hover:border-[#bfdbfe] hover:shadow-[0_10px_18px_-16px_rgba(37,99,235,0.35)] focus-visible:border-[#3b82f6] focus-visible:ring-1 focus-visible:ring-[#93c5fd]/60"
                          type="password"
                          placeholder="请输入密码"
                          autoComplete="current-password"
                          {...field}
                        />
                      </div>
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />

              <Button
                className="h-11 w-full rounded-xl bg-[#2563eb] font-bold text-white transition-all duration-200 hover:bg-[#1d4ed8] hover:shadow-[0_16px_30px_-20px_rgba(37,99,235,0.58)]"
                type="submit"
                disabled={isSubmitting || isBootstrapping}
              >
                {isSubmitting ? <LoaderCircle className="mr-2 h-4 w-4 animate-spin" /> : null}
                进入系统
              </Button>

              <Button
                className="h-10 w-full rounded-xl"
                type="button"
                variant="ghost"
                disabled={isSubmitting || isBootstrapping}
                onClick={() => setForgotPasswordOpen(true)}
              >
                <Mail className="mr-2 h-4 w-4" />
                忘记密码
              </Button>
            </form>
          </Form>

          <p className="text-center text-sm text-slate-500">
            还没有账号？{' '}
            <Link to="/register" className="font-medium text-[#2563eb] hover:text-[#1d4ed8] hover:underline">
              立即注册
            </Link>
          </p>
        </CardContent>
      </Card>

      <ForgotPasswordDialog open={forgotPasswordOpen} onOpenChange={setForgotPasswordOpen} />
    </div>
  );
}

function ForgotPasswordDialog({
  open,
  onOpenChange,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
}) {
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [recoveryUsername, setRecoveryUsername] = useState('');
  const [usernameLookupStatus, setUsernameLookupStatus] = useState<'idle' | 'loading' | 'found' | 'not-found' | 'error'>('idle');
  const form = useForm<ForgotPasswordFormValues>({
    resolver: zodResolver(forgotPasswordSchema),
    defaultValues: {
      email: '',
      newPassword: '',
      confirmPassword: '',
    },
  });
  const email = form.watch('email');

  useEffect(() => {
    const normalizedEmail = email.trim().toLowerCase();

    setRecoveryUsername('');

    if (!normalizedEmail) {
      setUsernameLookupStatus('idle');
      return;
    }

    if (!z.string().email().safeParse(normalizedEmail).success) {
      setUsernameLookupStatus('idle');
      return;
    }

    setUsernameLookupStatus('loading');
    let canceled = false;
    const timeoutId = window.setTimeout(async () => {
      try {
        const username = await lookupRecoveryUsernameByEmail({ email: normalizedEmail });

        if (canceled) {
          return;
        }

        if (username) {
          setRecoveryUsername(username);
          setUsernameLookupStatus('found');
          return;
        }

        setUsernameLookupStatus('not-found');
      } catch {
        if (!canceled) {
          setUsernameLookupStatus('error');
        }
      }
    }, 450);

    return () => {
      canceled = true;
      window.clearTimeout(timeoutId);
    };
  }, [email]);

  async function handleSubmit(values: ForgotPasswordFormValues) {
    setIsSubmitting(true);

    try {
      await resetPasswordByEmail({
        email: values.email,
        newPassword: values.newPassword,
      });
      toast.success('密码已重置，请使用新密码登录');
      onOpenChange(false);
      form.reset();
    } catch (error) {
      toast.error(error instanceof Error ? error.message : '密码重置失败');
    } finally {
      setIsSubmitting(false);
    }
  }

  function handleOpenChange(nextOpen: boolean) {
    if (!nextOpen) {
      form.reset();
      setRecoveryUsername('');
      setUsernameLookupStatus('idle');
    }

    onOpenChange(nextOpen);
  }

  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      <DialogContent className="sm:max-w-[460px]">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Mail className="h-5 w-5 text-blue-600" />
            忘记密码
          </DialogTitle>
          <DialogDescription>
            当前过渡版本暂不发送验证码，后续将接入邮箱验证。
          </DialogDescription>
        </DialogHeader>

        <Form {...form}>
          <form className="space-y-4" onSubmit={form.handleSubmit(handleSubmit)}>
            <FormField
              control={form.control}
              name="email"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>注册邮箱</FormLabel>
                  <FormControl>
                    <Input type="email" placeholder="请输入注册邮箱" autoComplete="email" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <FormItem>
              <FormLabel>注册用户名</FormLabel>
              <FormControl>
                <div className="relative">
                  <UserCircle2 className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400" />
                  <Input
                    className="pl-10"
                    value={recoveryUsername}
                    readOnly
                    placeholder={
                      usernameLookupStatus === 'loading'
                        ? '正在查询...'
                        : usernameLookupStatus === 'not-found'
                          ? '未找到匹配用户名'
                          : usernameLookupStatus === 'error'
                            ? '查询失败，请稍后重试'
                            : '输入注册邮箱后自动带出'
                    }
                  />
                </div>
              </FormControl>
            </FormItem>

            <FormField
              control={form.control}
              name="newPassword"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>新密码</FormLabel>
                  <FormControl>
                    <Input type="password" placeholder="请输入至少 6 位新密码" autoComplete="new-password" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <FormField
              control={form.control}
              name="confirmPassword"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>确认新密码</FormLabel>
                  <FormControl>
                    <Input type="password" placeholder="请再次输入新密码" autoComplete="new-password" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => handleOpenChange(false)} disabled={isSubmitting}>
                取消
              </Button>
              <Button type="submit" disabled={isSubmitting}>
                {isSubmitting ? <LoaderCircle className="mr-2 h-4 w-4 animate-spin" /> : null}
                重置密码
              </Button>
            </DialogFooter>
          </form>
        </Form>
      </DialogContent>
    </Dialog>
  );
}
