import React, { useState, useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { Eye, EyeOff, LogIn, Loader2, Mail, Lock, Shield, ArrowLeft, Settings } from 'lucide-react';
import { useNavigate, Link } from 'react-router-dom';
import useAuthStore from '../../../store/useAuthStore';
import { loginSchema, LoginFormData } from '../../../shared/utils/validationSchemas';
import { useCompanySettings } from '../../../shared/contexts/CompanySettingsContext';
import * as yup from 'yup';
import { toast } from 'react-toastify';
import Recaptcha from '../../../shared/components/Recaptcha';
import { recaptchaService } from '../../../features/system/services/systemSettingsService';
import { useAntibotForm } from '../hooks/useAntibotForm';
import HoneypotField from '../../../shared/components/HoneypotField';
import authService from '../services/authService';
import { getUserFriendlyError } from '../../../shared/utils/errorSanitizer';

const mfaTokenSchema = yup.object().shape({
  mfaToken: yup
    .string()
    .required('MFA token is required')
    .min(6, 'MFA token must be 6 digits')
    .max(8, 'MFA token must be 6-8 characters')
    .matches(/^\d+$|^[A-Z0-9]{8}$/, 'Invalid token format'),
});

type MFATokenFormData = yup.InferType<typeof mfaTokenSchema>;

const AdminLoginPage: React.FC = () => {
  const { isLoading, error, clearError, requiresMFA, clearMFA, isAuthenticated, userInfo } = useAuthStore();
  const { settings } = useCompanySettings();
  const navigate = useNavigate();
  
  const [showPassword, setShowPassword] = useState(false);
  
  const {
    honeypotValue,
    setHoneypotValue,
    recaptchaToken,
    setRecaptchaToken,
    validate: validateAntibot,
    rateLimitInfo,
  } = useAntibotForm({
    formId: 'admin-login',
    minTimeOnPage: 3000,
    minTimeToFill: 2000,
    requireRecaptcha: false,
    maxAttempts: 5,
    onValidationError: (errors) => {
      errors.forEach((err) => toast.error(err));
    },
  });
  
  const {
    register: registerMFA,
    handleSubmit: handleSubmitMFA,
    formState: { errors: mfaErrors },
  } = useForm<MFATokenFormData>({
    resolver: yupResolver(mfaTokenSchema),
    defaultValues: {
      mfaToken: '',
    },
  });

  useEffect(() => {
    if (!isLoading && isAuthenticated && !requiresMFA && userInfo) {
      const userWithRoleName = userInfo as typeof userInfo & { role_name?: string };
      const role = userInfo.role?.toLowerCase() || userWithRoleName.role_name?.toLowerCase();
      
      // Safety check - should not happen if onSubmit logic works correctly
      if (role !== 'admin') {
        navigate(`/${role}/login`, { replace: true });
        return;
      }
      
      navigate('/admin/dashboard', { replace: true });
    }
  }, [isLoading, isAuthenticated, requiresMFA, userInfo, navigate]);

  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<LoginFormData>({
    resolver: yupResolver(loginSchema),
    defaultValues: {
      email: '',
      password: '',
      rememberMe: false,
    },
  });

  const onSubmit = async (data: LoginFormData) => {
    try {
      clearError();
      
      // Validate antibot protection
      const isValid = await validateAntibot();
      if (!isValid) {
        return;
      }
      
      // Verify reCAPTCHA if token is provided
      if (recaptchaToken) {
        try {
          const verifyResponse = await recaptchaService.verifyRecaptcha(recaptchaToken);
          if (verifyResponse.status === 'error' || !verifyResponse.data.verified) {
            toast.error('reCAPTCHA verification failed. Please try again.');
            setRecaptchaToken(null);
            return;
          }
        } catch (error) {
          toast.error('reCAPTCHA verification failed. Please try again.');
          setRecaptchaToken(null);
          return;
        }
      }
      
      // Call login API directly to check role BEFORE showing success toast
      useAuthStore.setState({ isLoading: true, error: null });
      
      try {
        const response = await authService.login({
          email: data.email,
          password: data.password,
          rememberMe: data.rememberMe,
          expectedRole: 'admin',  // Admin login page only accepts admins
        });

        // Handle MFA requirement
        if (response.requires_mfa) {
          useAuthStore.setState({
            isLoading: false,
            requiresMFA: true,
            mfaUserId: response.user_id || null,
            pendingCredentials: {
              email: data.email,
              password: data.password,
              rememberMe: data.rememberMe,
              expectedRole: 'admin',
            },
            error: null,
          });
          setRecaptchaToken(null);
          return;
        }

        // Check if login was successful
        if (response.success || response.status === 'success') {
          const user = response.data?.user ?? null;

          if (!user) {
            throw new Error(response.message || 'Login failed.');
          }

          // Check role BEFORE setting authenticated state or showing success toast
          const userWithRoleName = user as typeof user & { role_name?: string };
          const role = user.role?.toLowerCase() || userWithRoleName.role_name?.toLowerCase();
          
          // Reject non-admin roles - show error and don't authenticate
          if (role !== 'admin') {
            // Call logout API to clear any server-side session
            await authService.logout().catch(() => {
              // Ignore logout errors
            });
            
            // Show error toast
            toast.error(`This login is only for administrators. Please use the ${role} login page at /${role}/login to access your account.`, {
              autoClose: 6000,
              position: 'top-center',
              toastId: 'role-error',
            });
            
            // Reset loading state
            useAuthStore.setState({
              isLoading: false,
              error: 'Invalid role for this login page',
            });
            
            setRecaptchaToken(null);
            
            // Navigate to the appropriate login page
            setTimeout(() => {
              navigate(`/${role}/login`, { replace: true });
            }, 2000);
            return;
          }

          // Only proceed with authentication if user is an admin
          // Store minimal userInfo in localStorage
          const minimalUserInfo = {
            id: user.id,
            name: user.name,
            email: user.email,
            role: user.role,
            avatar: user.avatar,
          };
          localStorage.setItem('userInfo', JSON.stringify(minimalUserInfo));

          // Update auth store state
          useAuthStore.setState({
            token: null,
            userInfo: user,
            isAuthenticated: true,
            isLoading: false,
            error: null,
            requiresMFA: false,
            mfaUserId: null,
            pendingCredentials: null,
          });

          // Show success toast only for admins
          toast.success('Login successful!');
          setRecaptchaToken(null);
        }
      } catch (error: unknown) {
        const errorMessage = getUserFriendlyError(error) || 'Login failed. Please try again.';
        useAuthStore.setState({
          isLoading: false,
          error: errorMessage,
          isAuthenticated: false,
          requiresMFA: false,
          mfaUserId: null,
          pendingCredentials: null,
        });
        toast.error(errorMessage);
        setRecaptchaToken(null);
      }
    } catch (error) {
      if (import.meta.env.DEV) {
        console.error('Login error:', error);
      }
      setRecaptchaToken(null);
    }
  };

  const onSubmitMFA = async (data: MFATokenFormData) => {
    try {
      clearError();
      
      // Get pending credentials from store
      const state = useAuthStore.getState();
      if (!state.pendingCredentials) {
        toast.error('No pending login credentials');
        return;
      }

      // Call MFA verification API directly to check role before showing success
      useAuthStore.setState({ isLoading: true, error: null });
      
      try {
        const credentials = {
          ...state.pendingCredentials,
          mfaToken: data.mfaToken,
          expectedRole: 'admin',  // Admin login page only accepts admins
        };

        const response = await authService.login(credentials);

        if (response.success || response.status === 'success') {
          const user = response.data?.user ?? null;

          if (!user) {
            throw new Error(response.message || 'MFA verification failed.');
          }

          // Check role BEFORE setting authenticated state or showing success toast
          const userWithRoleName = user as typeof user & { role_name?: string };
          const role = user.role?.toLowerCase() || userWithRoleName.role_name?.toLowerCase();
          
          // Reject non-admin roles - show error and don't authenticate
          if (role !== 'admin') {
            // Call logout API to clear any server-side session
            await authService.logout().catch(() => {
              // Ignore logout errors
            });
            
            // Show error toast
            toast.error(`This login is only for administrators. Please use the ${role} login page at /${role}/login to access your account.`, {
              autoClose: 6000,
              position: 'top-center',
              toastId: 'role-error',
            });
            
            // Reset auth store state
            useAuthStore.setState({
              isLoading: false,
              error: 'Invalid role for this login page',
              requiresMFA: false,
              mfaUserId: null,
              pendingCredentials: null,
            });
            
            // Navigate to the appropriate login page
            setTimeout(() => {
              navigate(`/${role}/login`, { replace: true });
            }, 2000);
            return;
          }

          // Only proceed with authentication if user is an admin
          // Store minimal userInfo in localStorage
          const minimalUserInfo = {
            id: user.id,
            name: user.name,
            email: user.email,
            role: user.role,
            avatar: user.avatar,
          };
          localStorage.setItem('userInfo', JSON.stringify(minimalUserInfo));

          // Update auth store state
          useAuthStore.setState({
            token: null,
            userInfo: user,
            isAuthenticated: true,
            isLoading: false,
            error: null,
            requiresMFA: false,
            mfaUserId: null,
            pendingCredentials: null,
          });

          // Show success toast only for admins
          toast.success('Login successful!');
        }
      } catch (error: unknown) {
        const errorMessage = getUserFriendlyError(error) || 'MFA verification failed. Please try again.';
        useAuthStore.setState({
          isLoading: false,
          error: errorMessage,
          requiresMFA: true, // Keep MFA state in case of error
        });
        toast.error(errorMessage);
      }
    } catch (error) {
      if (import.meta.env.DEV) {
        console.error('MFA verification error:', error);
      }
    }
  };

  const handleBackToLogin = () => {
    clearMFA();
    clearError();
  };

  return (
    <div className="min-h-screen bg-gradient-to-br from-gray-50 via-white to-gray-50 flex items-center justify-center p-4">
      <div className="w-full max-w-md">
        <div className="bg-white rounded-2xl shadow-2xl border border-gray-200/50 overflow-hidden">
          <div className="bg-gradient-to-r from-purple-600 via-purple-500 to-indigo-600 p-6 sm:p-8 text-center">
            <div className="flex justify-center mb-4">
              {settings.company_logo_url ? (
                <img 
                  src={settings.company_logo_url.startsWith('http') 
                    ? settings.company_logo_url 
                    : `${import.meta.env.VITE_API_URL || 'http://localhost:8000'}${settings.company_logo_url}`}
                  alt={settings.company_name || 'Logo'}
                  className="h-16 w-auto max-w-[150px] object-contain bg-white/20 p-2 rounded-lg"
                />
              ) : (
                <div className="relative p-3 bg-white/20 backdrop-blur-sm rounded-full">
                  <Settings className="w-10 h-10 text-white" />
                </div>
              )}
            </div>
            <h1 className="text-2xl sm:text-3xl font-bold text-white mb-2">Admin Login</h1>
            <p className="text-purple-100 text-sm">Access your admin dashboard</p>
          </div>

          <div className="p-6 sm:p-8">
            {requiresMFA ? (
              <form onSubmit={handleSubmitMFA(onSubmitMFA)} className="space-y-5">
                {error && (
                  <div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg text-sm">
                    {error}
                  </div>
                )}

                <div>
                  <label htmlFor="mfaToken" className="block text-sm font-medium text-gray-700 mb-2">
                    Authentication Code
                  </label>
                  <div className="relative">
                    <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                      <Shield className="h-5 w-5 text-gray-400" />
                    </div>
                    <input
                      {...registerMFA('mfaToken')}
                      id="mfaToken"
                      type="text"
                      autoComplete="one-time-code"
                      maxLength={8}
                      className={`w-full pl-10 pr-4 py-3 border rounded-lg text-center tracking-widest ${
                        mfaErrors.mfaToken ? 'border-red-300 focus:ring-red-500' : 'border-gray-300 focus:ring-purple-500'
                      }`}
                      placeholder="000000"
                    />
                  </div>
                  {mfaErrors.mfaToken && (
                    <p className="mt-1 text-sm text-red-600">{mfaErrors.mfaToken.message}</p>
                  )}
                </div>

                <button
                  type="submit"
                  disabled={isLoading}
                  className="w-full bg-gradient-to-r from-purple-600 to-indigo-600 text-white py-3 px-4 rounded-lg font-semibold hover:from-purple-700 hover:to-indigo-700 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center"
                >
                  {isLoading ? (
                    <>
                      <Loader2 className="animate-spin mr-2 h-5 w-5" />
                      Verifying...
                    </>
                  ) : (
                    <>
                      <Shield className="mr-2 h-5 w-5" />
                      Verify
                    </>
                  )}
                </button>

                <div className="text-center">
                  <button
                    type="button"
                    onClick={handleBackToLogin}
                    className="inline-flex items-center text-sm font-medium text-gray-600 hover:text-gray-900"
                  >
                    <ArrowLeft className="mr-1 h-4 w-4" />
                    Back to Login
                  </button>
                </div>
              </form>
            ) : (
              <form onSubmit={handleSubmit(onSubmit)} className="space-y-5">
                <HoneypotField value={honeypotValue} onChange={setHoneypotValue} />
                
                {error && (
                  <div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg text-sm">
                    {error}
                  </div>
                )}
                
                {rateLimitInfo && !rateLimitInfo.allowed && (
                  <div className="bg-yellow-50 border border-yellow-200 text-yellow-700 px-4 py-3 rounded-lg text-sm">
                    <p className="font-medium">Too many login attempts.</p>
                    <p className="text-xs mt-1">
                      Please try again after {new Date(rateLimitInfo.resetTime).toLocaleTimeString()}
                    </p>
                  </div>
                )}

                <div>
                  <label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-2">
                    Email
                  </label>
                  <div className="relative">
                    <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                      <Mail className="h-5 w-5 text-gray-400" />
                    </div>
                    <input
                      {...register('email')}
                      id="email"
                      type="email"
                      autoComplete="email"
                      className={`w-full pl-10 pr-4 py-3 border rounded-lg ${
                        errors.email ? 'border-red-300 focus:ring-red-500' : 'border-gray-300 focus:ring-purple-500'
                      }`}
                      placeholder="email@example.com"
                    />
                  </div>
                  {errors.email && (
                    <p className="mt-1 text-sm text-red-600">{errors.email.message}</p>
                  )}
                </div>

                <div>
                  <label htmlFor="password" className="block text-sm font-medium text-gray-700 mb-2">
                    Password
                  </label>
                  <div className="relative">
                    <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                      <Lock className="h-5 w-5 text-gray-400" />
                    </div>
                    <input
                      {...register('password')}
                      id="password"
                      type={showPassword ? 'text' : 'password'}
                      autoComplete="current-password"
                      className={`w-full pl-10 pr-10 py-3 border rounded-lg ${
                        errors.password ? 'border-red-300 focus:ring-red-500' : 'border-gray-300 focus:ring-purple-500'
                      }`}
                      placeholder="••••••••"
                    />
                    <button
                      type="button"
                      onClick={() => setShowPassword(!showPassword)}
                      className="absolute inset-y-0 right-0 pr-3 flex items-center"
                    >
                      {showPassword ? (
                        <EyeOff className="h-5 w-5 text-gray-400" />
                      ) : (
                        <Eye className="h-5 w-5 text-gray-400" />
                      )}
                    </button>
                  </div>
                  {errors.password && (
                    <p className="mt-1 text-sm text-red-600">{errors.password.message}</p>
                  )}
                </div>

                <div className="flex items-center">
                  <input
                    {...register('rememberMe')}
                    id="rememberMe"
                    type="checkbox"
                    className="h-4 w-4 text-purple-600 focus:ring-purple-500 border-gray-300 rounded"
                  />
                  <label htmlFor="rememberMe" className="ml-2 block text-sm text-gray-700">
                    Remember me
                  </label>
                </div>

                <div className="flex justify-center">
                  <Recaptcha
                    onChange={(token) => setRecaptchaToken(token)}
                    onError={(error) => {
                      if (import.meta.env.DEV) {
                        console.error('reCAPTCHA error:', error);
                      }
                      setRecaptchaToken(null);
                    }}
                    theme="light"
                    size="normal"
                  />
                </div>

                <button
                  type="submit"
                  disabled={isLoading}
                  className="w-full bg-gradient-to-r from-purple-600 to-indigo-600 text-white py-3 px-4 rounded-lg font-semibold hover:from-purple-700 hover:to-indigo-700 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center"
                >
                  {isLoading ? (
                    <>
                      <Loader2 className="animate-spin mr-2 h-5 w-5" />
                      Processing...
                    </>
                  ) : (
                    <>
                      <LogIn className="mr-2 h-5 w-5" />
                      Sign In
                    </>
                  )}
                </button>
              </form>
            )}

            <div className="mt-6 text-center">
              <Link
                to="/"
                className="text-sm text-gray-600 hover:text-gray-900"
              >
                ← Back to Home
              </Link>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default AdminLoginPage;

