import React, { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components';
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom';
import { isAxiosError } from 'axios';
import { HiMoon, HiSun } from 'react-icons/hi';
import { useLocale } from '@/app/providers/LocaleProvider';
import { useTheme } from '@/app/providers/ThemeProvider';
import { Button, Card, Input } from '@/shared/components/ui';
import { ROUTES } from '@/shared/constants/routes';
import { OtpInput } from '@/features/auth/components/OtpInput';
import { authService } from '@/features/auth/services/authService';
import { useAuthStore } from '@/features/auth/store/authStore';
import { useBrandingLogos } from '@/shared/hooks/useBrandingLogos';

const Container = styled.div`
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: ${({ theme }) => theme.colors.surface};
  padding: ${({ theme }) => theme.spacing[4]};
`;

const LogoBranding = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: ${({ theme }) => theme.spacing[4]};
  margin-bottom: ${({ theme }) => theme.spacing[8]};
`;

const LogoImage = styled.img`
  width: min(220px, 80vw);
  height: auto;
`;

const BrandDescription = styled.p`
  max-width: 28rem;
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  line-height: 1.6;
  color: ${({ theme }) => theme.colors.text.secondary};
  text-align: center;
  margin: 0;
`;

const LoginCard = styled(Card)`
  width: 100%;
  max-width: 400px;
`;

const Title = styled.h1`
  font-size: ${({ theme }) => theme.typography.fontSize['2xl']};
  margin-bottom: ${({ theme }) => theme.spacing[2]};
  text-align: center;
`;

const Subtitle = styled.p`
  color: ${({ theme }) => theme.colors.text.secondary};
  text-align: center;
  margin-bottom: ${({ theme }) => theme.spacing[6]};
`;

const Form = styled.form`
  display: flex;
  flex-direction: column;
  gap: ${({ theme }) => theme.spacing[4]};
`;

const ErrorText = styled.p`
  color: ${({ theme }) => theme.colors.error};
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  text-align: center;
  margin: 0;
`;

const HintText = styled.p`
  color: ${({ theme }) => theme.colors.text.secondary};
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  text-align: center;
  margin: 0;
`;

const CheckboxRow = styled.label`
  display: flex;
  align-items: center;
  gap: ${({ theme }) => theme.spacing[2]};
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  color: ${({ theme }) => theme.colors.text.secondary};
  cursor: pointer;
`;

const ThemeToggle = styled.button`
  position: fixed;
  top: ${({ theme }) => theme.spacing[4]};
  right: ${({ theme }) => theme.spacing[4]};
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: ${({ theme }) => theme.spacing[2]};
  background-color: ${({ theme }) => theme.colors.background};
  border: 1px solid ${({ theme }) => theme.colors.border};
  border-radius: ${({ theme }) => theme.borderRadius.md};
  cursor: pointer;
  color: ${({ theme }) => theme.colors.text.secondary};
  transition: all ${({ theme }) => theme.transitions.fast};
  
  &:hover {
    background-color: ${({ theme }) => theme.colors.gray[100]};
    color: ${({ theme }) => theme.colors.text.primary};
  }
  
  svg {
    width: 20px;
    height: 20px;
  }
`;

const LanguageToggle = styled(ThemeToggle)`
  right: ${({ theme }) => theme.spacing[20]};
`;

const DEFAULT_RESEND_SECONDS = 60;

type Step = 'email' | 'otp' | 'magicLinkSent';
type AuthMode = 'otp' | 'magicLink';

const LoginPage: React.FC = () => {
  const { t, locale, setLocale } = useLocale();
  const { mode, toggleTheme } = useTheme();
  const { square } = useBrandingLogos();
  const navigate = useNavigate();
  const location = useLocation();
  const [searchParams] = useSearchParams();
  const login = useAuthStore((state) => state.login);

  const postLoginPath = React.useMemo(() => {
    const redirect = searchParams.get('redirect');
    if (redirect && redirect.startsWith('/')) {
      return redirect;
    }
    const from = (location.state as { from?: string } | null)?.from;
    if (from && from.startsWith('/')) {
      return from;
    }
    return ROUTES.DASHBOARD;
  }, [location.state, searchParams]);

  const [step, setStep] = useState<Step>('email');
  const [authMode, setAuthMode] = useState<AuthMode>('otp');
  const [email, setEmail] = useState('');
  const [otp, setOtp] = useState('');
  const [rememberDevice, setRememberDevice] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [resendSeconds, setResendSeconds] = useState(0);

  useEffect(() => {
    if (resendSeconds <= 0) {
      return undefined;
    }

    const timer = window.setInterval(() => {
      setResendSeconds((current) => (current > 0 ? current - 1 : 0));
    }, 1000);

    return () => window.clearInterval(timer);
  }, [resendSeconds]);

  const handleRequestOtp = useCallback(
    async (event?: React.FormEvent) => {
      event?.preventDefault();
      setError(null);
      setIsLoading(true);

      try {
        await authService.ensureCsrfCookie();
        const response = await authService.requestOtp(email.trim().toLowerCase());
        setAuthMode('otp');
        setStep('otp');
        setOtp('');
        setResendSeconds(response.retry_after_seconds ?? DEFAULT_RESEND_SECONDS);
      } catch (err: unknown) {
        if (isAxiosError(err) && err.response?.status === 429) {
          const retryAfter = Number(err.response.data?.retry_after_seconds ?? DEFAULT_RESEND_SECONDS);
          setResendSeconds(retryAfter);
          setError(t('auth:messages.resendCooldown', { seconds: retryAfter }));
        } else {
          setError(t('auth:messages.loginError'));
        }
      } finally {
        setIsLoading(false);
      }
    },
    [email, t],
  );

  const handleVerifyOtp = useCallback(
    async (event: React.FormEvent) => {
      event.preventDefault();
      setError(null);
      setIsLoading(true);

      try {
        const user = await authService.verifyOtp(
          email.trim().toLowerCase(),
          otp,
          rememberDevice,
        );
        login(user);
        useAuthStore.setState({ isLoading: false });
        navigate(postLoginPath, { replace: true });
      } catch (err: unknown) {
        if (isAxiosError(err) && err.response?.status === 422) {
          setError(t('auth:messages.invalidOtp'));
        } else if (isAxiosError(err) && err.response?.status === 429) {
          setError(t('auth:messages.tooManyAttempts'));
        } else {
          setError(t('auth:messages.loginError'));
        }
      } finally {
        setIsLoading(false);
      }
    },
    [email, login, navigate, otp, postLoginPath, rememberDevice, t],
  );

  const handleRequestMagicLink = useCallback(async () => {
    setError(null);
    setIsLoading(true);

    try {
      await authService.ensureCsrfCookie();
      await authService.requestMagicLink(email.trim().toLowerCase());
      setAuthMode('magicLink');
      setStep('magicLinkSent');
      setError(null);
      setResendSeconds(DEFAULT_RESEND_SECONDS);
    } catch (err: unknown) {
      if (isAxiosError(err) && err.response?.status === 429) {
        const retryAfter = Number(err.response.data?.retry_after_seconds ?? DEFAULT_RESEND_SECONDS);
        setResendSeconds(retryAfter);
        setError(t('auth:messages.resendCooldown', { seconds: retryAfter }));
      } else {
        setError(t('auth:messages.loginError'));
      }
    } finally {
      setIsLoading(false);
    }
  }, [email, t]);

  const handleResend = useCallback(async () => {
    if (resendSeconds > 0 || isLoading) {
      return;
    }

    if (authMode === 'magicLink') {
      await handleRequestMagicLink();
    } else {
      await handleRequestOtp();
    }
  }, [authMode, handleRequestMagicLink, handleRequestOtp, isLoading, resendSeconds]);

  const handleBackToEmail = () => {
    setStep('email');
    setOtp('');
    setError(null);
    setAuthMode('otp');
  };

  return (
    <Container>
      <LanguageToggle type="button" onClick={() => setLocale(locale === 'en' ? 'ar' : 'en')}>
        {locale === 'en' ? 'ع' : 'EN'}
      </LanguageToggle>

      <ThemeToggle type="button" onClick={toggleTheme}>
        {mode === 'light' ? <HiMoon /> : <HiSun />}
      </ThemeToggle>

      <LogoBranding>
        <LogoImage src={square} alt={t('common:app.logoAlt')} />
        <BrandDescription>{t('auth:login.description')}</BrandDescription>
      </LogoBranding>

      <LoginCard variant="elevated" padding="lg">
        <Title>{t('auth:login.title')}</Title>
        <Subtitle>
          {step === 'email' ? t('auth:login.subtitle') :
            step === 'magicLinkSent' ? t('auth:magicLink.checkEmail') :
              t('auth:login.otpSubtitle')}
        </Subtitle>

        {step === 'email' ? (
          <Form onSubmit={handleRequestOtp}>
            <Input
              type="email"
              name="email"
              data-testid="login-email"
              label={t('auth:login.email')}
              placeholder={t('auth:login.emailPlaceholder')}
              value={email}
              onChange={(event) => setEmail(event.target.value)}
              autoComplete="email"
              required
              fullWidth
            />
            {error && <ErrorText>{error}</ErrorText>}
            <Button
              type="submit"
              variant="primary"
              size="lg"
              fullWidth
              data-testid="login-send-otp"
              disabled={isLoading || !email.trim()}
              loading={isLoading}
            >
              {t('auth:login.sendOtp')}
            </Button>
            <Button
              type="button"
              variant="ghost"
              size="sm"
              fullWidth
              data-testid="login-send-magic-link"
              onClick={handleRequestMagicLink}
              disabled={isLoading || !email.trim()}
            >
              {t('auth:login.sendMagicLink')}
            </Button>
          </Form>
        ) : step === 'magicLinkSent' ? (
          <Form>
            <HintText>{t('auth:magicLink.linkSentTo', { email })}</HintText>
            {error && <ErrorText>{error}</ErrorText>}
            <Button
              type="button"
              variant="ghost"
              size="md"
              fullWidth
              disabled={resendSeconds > 0 || isLoading}
              onClick={handleResend}
            >
              {resendSeconds > 0
                ? t('auth:login.resendIn', { seconds: resendSeconds })
                : t('auth:magicLink.resendLink')}
            </Button>
            <Button type="button" variant="ghost" size="sm" fullWidth onClick={handleBackToEmail}>
              {t('auth:login.changeEmail')}
            </Button>
          </Form>
        ) : (
          <Form onSubmit={handleVerifyOtp}>
            <HintText>{t('auth:login.codeSentTo', { email })}</HintText>
            <OtpInput
              label={t('auth:login.otpLabel')}
              value={otp}
              onChange={setOtp}
              disabled={isLoading}
              hasError={!!error}
              autoFocus
              data-testid="login-otp"
            />
            <CheckboxRow>
              <input
                type="checkbox"
                checked={rememberDevice}
                onChange={(event) => setRememberDevice(event.target.checked)}
              />
              {t('auth:login.rememberDevice')}
            </CheckboxRow>
            {error && <ErrorText>{error}</ErrorText>}
            <Button
              type="submit"
              variant="primary"
              size="lg"
              fullWidth
              data-testid="login-verify-otp"
              disabled={isLoading || otp.length !== 6}
              loading={isLoading}
            >
              {t('auth:login.verifyOtp')}
            </Button>
            <Button
              type="button"
              variant="ghost"
              size="md"
              fullWidth
              disabled={resendSeconds > 0 || isLoading}
              onClick={handleResend}
            >
              {resendSeconds > 0
                ? t('auth:login.resendIn', { seconds: resendSeconds })
                : t('auth:login.resendOtp')}
            </Button>
            <Button type="button" variant="ghost" size="sm" fullWidth onClick={handleBackToEmail}>
              {t('auth:login.changeEmail')}
            </Button>
          </Form>
        )}
      </LoginCard>
    </Container>
  );
};

export default LoginPage;
