import { useState, useEffect, useRef } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { Link, useNavigate } from 'react-router-dom';

import { useAuth } from '@/context/AuthContext.jsx';
import { useNotification } from '@/components/context/NotificationContext.jsx';
import apiClient from '@/services/apiClient.js';
import { getUserManagementSchema } from '@/schemas/userManagementSchema.js';

import Button from '@/components/tailAdmin/Button';

// Internal Components
import RegisterHeader from './components/RegisterHeader.jsx';
import RegisterFormFields from './components/RegisterFormFields.jsx';
import RoleSelector from './components/RoleSelector.jsx';

const Register = () => {
    const { setCurrentUser } = useAuth();
    const navigate = useNavigate();
    const { showError, showSuccess } = useNotification();

    const [loading, setLoading] = useState(false);
    const [showPassword, setShowPassword] = useState(false);
    const [isServiceProvider, setIsServiceProvider] = useState(false);
    const [selectedServices, setSelectedServices] = useState([]);

    // Email Verification State
    const [emailVerified, setEmailVerified] = useState(false);
    const [otpSent, setOtpSent] = useState(false);
    const [sendingOtp, setSendingOtp] = useState(false);
    const [verifyingOtp, setVerifyingOtp] = useState(false);
    const [timeLeft, setTimeLeft] = useState(0);

    const timerRef = useRef(null);
    const otpRef = useRef(null);

    const formSchema = getUserManagementSchema(false); // register schema

    const {
        control,
        handleSubmit,
        getValues,
        formState: { errors },
    } = useForm({
        resolver: zodResolver(formSchema),
    });

    // Initialize timer from sessionStorage on mount (Security: Moved from localStorage)
    useEffect(() => {
        const savedExpiry = sessionStorage.getItem('otpExpiresAt');
        const savedEmail = sessionStorage.getItem('otpEmail');

        if (savedExpiry && savedEmail) {
            const remainingSeconds = Math.floor((parseInt(savedExpiry, 10) - Date.now()) / 1000);
            if (remainingSeconds > 0) {
                setTimeLeft(remainingSeconds);
                setOtpSent(true);
            } else {
                sessionStorage.removeItem('otpExpiresAt');
                sessionStorage.removeItem('otpEmail');
            }
        }
    }, []);

    useEffect(() => {
        if (timeLeft > 0) {
            timerRef.current = setTimeout(() => setTimeLeft((prev) => prev - 1), 1000);
        } else if (timeLeft === 0 && otpSent) {
            sessionStorage.removeItem('otpExpiresAt');
        }
        return () => clearTimeout(timerRef.current);
    }, [timeLeft, otpSent]);

    const formatTime = (seconds) => {
        const m = Math.floor(seconds / 60);
        const s = seconds % 60;
        return `${m}:${s < 10 ? '0' : ''}${s}`;
    };

    const handleSendOtp = async (emailValue) => {
        if (!emailValue) return;
        try {
            setSendingOtp(true);
            const res = await apiClient.post('/auth/send-register-otp', { email: emailValue });
            showSuccess(res.message);

            const expirySecs = res.expiresIn || 120;
            setOtpSent(true);
            setTimeLeft(expirySecs);

            // Persist timer in sessionStorage
            sessionStorage.setItem('otpExpiresAt', (Date.now() + expirySecs * 1000).toString());
            sessionStorage.setItem('otpEmail', emailValue);
        } catch (err) {
            if (err?.response?.status === 429 && err.response.data.remainingSeconds) {
                const rem = err.response.data.remainingSeconds;
                showSuccess('Restored active countdown for this email.');
                setOtpSent(true);
                setTimeLeft(rem);
                sessionStorage.setItem('otpExpiresAt', (Date.now() + rem * 1000).toString());
                sessionStorage.setItem('otpEmail', emailValue);
            } else {
                showError(err?.message || 'Failed to send OTP.');
                setTimeLeft(0);
                sessionStorage.removeItem('otpExpiresAt');
            }
        } finally {
            setSendingOtp(false);
        }
    };

    const handleVerifyOtp = async (emailValue, otpString) => {
        if (!otpString || otpString.length !== 6) return;
        try {
            setVerifyingOtp(true);
            const res = await apiClient.post('/auth/verify-register-otp', { email: emailValue, otp: otpString });
            showSuccess(res.message);
            setEmailVerified(true);
            setOtpSent(false);
            setTimeLeft(0);
            sessionStorage.removeItem('otpExpiresAt');
            sessionStorage.removeItem('otpEmail');
        } catch (err) {
            showError(err?.message || 'Invalid OTP.');
            if (otpRef.current) otpRef.current.reset();
        } finally {
            setVerifyingOtp(false);
        }
    };

    const handleVerifyOtpWrapper = (otpString) => {
        const targetEmail = getValues('email') || sessionStorage.getItem('otpEmail');
        handleVerifyOtp(targetEmail, otpString);
    };

    const handleServiceProviderChange = (checked) => {
        setIsServiceProvider(checked);
        if (!checked) {
            setSelectedServices([]);
        }
    };

    const handleServiceChange = (event) => {
        const { value, checked } = event.target;
        if (checked) {
            setSelectedServices((prev) => [...prev, value]);
        } else {
            setSelectedServices((prev) => prev.filter((service) => service !== value));
        }
    };

    const onSubmit = async (data) => {
        const { firstName, lastName, email, password } = data;

        try {
            if (!emailVerified) {
                showError('Please verify your email address before signing up.');
                return;
            }

            if (isServiceProvider && selectedServices.length === 0) {
                showError('Please select at least one service (Hotel or Travel) to register as a service provider.');
                return;
            }

            setLoading(true);

            const response = await apiClient.post('/auth/register', {
                firstName,
                lastName,
                email,
                password,
                phone: data.phone || undefined,
                cnic: data.cnic || undefined,
                isServiceProvider,
                services: selectedServices,
            });

            const resData = response?.data || response;
            const { user, token, accessToken } = resData;
            const finalToken = token || accessToken;

            if (finalToken) {
                localStorage.setItem('authToken', finalToken);
                localStorage.setItem('currentUser', JSON.stringify(user));
            }

            if (typeof setCurrentUser === 'function') {
                setCurrentUser(user);
            }

            const displayName = `${user.firstName || ''} ${user.lastName || ''}`.trim() || 'User';

            if (user.role === 'admin') {
                navigate('/admin-panel');
                showSuccess(`Welcome, ${displayName}!`, 'Registration Successful');
            } else if (user.role === 'service-provider') {
                const providerName = `${user.firstName || ''} ${user.lastName || ''}`.trim() || 'Service Provider';
                showSuccess(`Welcome, ${providerName}!`, 'Registration Successful');
                navigate('/service-provider');
            } else {
                showSuccess(`Welcome, ${displayName}!`, 'Registration Successful');
                navigate('/traveller/dashboard');
            }
        } catch (err) {
            showError(err.message || 'Something went wrong. Please try again.');
        } finally {
            setLoading(false);
        }
    };

    return (
        <main className="relative px-4 py-6 bg-white z-1 dark:bg-gray-900 sm:p-0">
            <div className="relative flex flex-col justify-center w-full min-h-screen dark:bg-gray-900 sm:p-0">
                <div className="flex flex-col flex-1 w-full overflow-y-auto no-scrollbar">
                    <RegisterHeader />

                    <div className="flex flex-col justify-center flex-1 w-full max-w-md mx-auto">
                        <form onSubmit={handleSubmit(onSubmit)} className="space-y-5 mt-2">
                            <RegisterFormFields
                                control={control}
                                errors={errors}
                                emailVerified={emailVerified}
                                sendingOtp={sendingOtp}
                                otpSent={otpSent}
                                timeLeft={timeLeft}
                                formatTime={formatTime}
                                handleSendOtp={handleSendOtp}
                                showPassword={showPassword}
                                setShowPassword={setShowPassword}
                                isServiceProvider={isServiceProvider}
                                setEmailVerified={setEmailVerified}
                                setOtpSent={setOtpSent}
                                setTimeLeft={setTimeLeft}
                                verifyingOtp={verifyingOtp}
                                handleVerifyOtpWrapper={handleVerifyOtpWrapper}
                                otpRef={otpRef}
                            />

                            <RoleSelector
                                isServiceProvider={isServiceProvider}
                                selectedServices={selectedServices}
                                handleServiceProviderChange={handleServiceProviderChange}
                                handleServiceChange={handleServiceChange}
                            />

                            <div>
                                <Button size="sm" className="w-full" type="submit" disabled={loading || !emailVerified}>
                                    {loading ? 'Creating Account...' : 'Sign Up'}
                                </Button>
                            </div>
                        </form>

                        <div className="mt-5">
                            <p className="text-sm font-normal text-center text-gray-700 dark:text-gray-400 sm:text-start mb-6">
                                Already have an account?{' '}
                                <Link
                                    to="/login"
                                    className="text-brand-500 hover:text-brand-600 dark:text-brand-400"
                                >
                                    Sign In
                                </Link>
                            </p>
                        </div>
                    </div>
                </div>
            </div>
        </main>
    );
};

export default Register;
