'use client'
/* 
  This is the create profile component.
  It contains the following components:
  - CreateProfile
*/
import { RootState } from '@/redux/slices'
import { commonActions } from '@/redux/slices/Common/commonSlice'
import { AppDispatch } from '@/redux/store'
import { checkUserNameAvailability, signUp } from '@/redux/thunks/Auth/authentication.thunk'
import { SignUpPayload } from '@/redux/types/authenticationTypes'
import { Toast } from '@/src/components/Toast'
import { LRFFlowContent } from '@/src/types/StaticContent/lrfflow.content.type'
import { formatDateYYYYMMDD, setFirstCharCapital } from '@/src/utils/commonFunctions'
import { COMMON_VARS, REGEX, STRENGTH_LEVELS } from '@/src/utils/commonVariables'
import { useDebounce } from '@/src/utils/customHooks/useDebounce'
import { getPasswordStrength } from '@/src/utils/passwordValidation'
import Routes from '@/src/utils/RouteConstants'
import { zodResolver } from '@hookform/resolvers/zod'
import Link from 'next/link'
import { useRouter } from 'next/navigation'
import React, { useEffect, useState } from 'react'
import { Controller, useForm } from 'react-hook-form'
import { useDispatch, useSelector } from 'react-redux'
import { z } from 'zod'
import { SignUpFormData } from '../../../Form/AuthTypes/AuthTypes'
import PasswordValidations from '../../../Form/PasswordValidations/PasswordValidations'
import styles from './CreateProfile.module.scss'
import ForgotPassword from './ForgotPassword'
import LoginForm from './LoginForm'
import DatePickerItem from '@/src/components/DatePickerItem'

type FieldType = "userName" | "email"; // Define valid types for the field

const CreateProfile: React.FC<{ CreateProfileContent: LRFFlowContent }> = ({ CreateProfileContent }) => {

    const router = useRouter()
    const dispatch = useDispatch<AppDispatch>()
    const [passwordStrength, setPasswordStrength] = useState(0);
    const [activeCount, setActiveCount] = useState(0);
    const [strengthClass, setStrengthClass] = useState("");
    const [isForgotPassword, setIsForgotPassword] = useState(false)
    const { LRFFlow } = useSelector((state: RootState) => state.common);
    const [isActiveTab, setIsActiveTab] = useState(LRFFlow ? LRFFlow : 'create')
    const [userNameAvailable, setUserNameAvailable] = useState(false);
    const [emailNotAvailabilityMessage, setEmailNotAvailabilityMessage] = useState('');
    const { LRFData } = useSelector((state: RootState) => state.common);
    const { viewBookingData } = useSelector((state: RootState) => state.booking);
    const [showPassword, setShowPassword] = useState(false);

    /**
    * Schema for validating user sign-up form data using Zod.
    * This schema ensures all required fields are filled with valid data
    * and enforces specific validation rules for each input.
    */
    const SignUpSchema = z.object({
        /**
         * First Name - Required and must match the defined name pattern.
         */
        firstName: z
            .string()
            .min(1, { message: CreateProfileContent.FORM.FIRST_NAME_REQUIRED }) // Required field
            .regex(REGEX.NAME, { message: CreateProfileContent.FORM.FIRST_NAME_INVALID }) // Must follow name pattern
            .trim(), // Removes leading/trailing spaces

        /**
         * Last Name - Required and must match the defined name pattern.
         */
        lastName: z
            .string()
            .min(1, { message: CreateProfileContent.FORM.LAST_NAME_REQUIRED }) // Required field
            .regex(REGEX.NAME, { message: CreateProfileContent.FORM.LAST_NAME_INVALID }) // Must follow name pattern
            .trim(), // Removes leading/trailing spaces
        /**
         * User Name - Required and must match the defined name pattern.
         */
        userName: z
            .string()
            .min(1, { message: CreateProfileContent.FORM.USER_NAME_REQUIRED }) // Required field
            .min(5, { message: CreateProfileContent.FORM.USER_NAME_MIN_LENGTH })
            .regex(REGEX.NAME, { message: CreateProfileContent.FORM.USER_NAME_INVALID }) // Must follow name pattern
            .trim(), // Removes leading/trailing spaces

        /**
         * Email - Required and must match the defined email pattern.
         */
        email: z
            .string()
            .min(1, { message: CreateProfileContent.FORM.EMAIL_REQUIRED }) // Required field
            .regex(REGEX.EMAIL, { message: CreateProfileContent.FORM.EMAIL_INVALID }), // Must follow email pattern

        dateOfBirth: z.date({
            message: CreateProfileContent.FORM.DATE_OF_BIRTH_REQUIRED
        }),

        /**
         * Password - Required, must have a minimum of 8 characters.
         */
        password: z
            .string()
            .min(1, { message: CreateProfileContent.FORM.PASSWORD_REQUIRED }) // Required field
            .min(COMMON_VARS.MIN_PASSOWRD_LENGTH, { message: CreateProfileContent.FORM.PASSWORD_MIN_LENGTH }) // Minimum 8 characters
            .regex(REGEX.PASSWORD, { message: CreateProfileContent.FORM.PASSWORD_INVALID }) // Must follow password pattern
            .trim(), // Removes leading/trailing spaces
    });


    /**
     * Initializes the useForm hook for managing form state and validation.
     *
     * @typedef {SignUpFormData} - The expected data structure for the sign-up form.
     */
    const {
        handleSubmit,
        formState: { errors },
        register,
        watch,
        setValue,
        clearErrors,
        setError,
        trigger,
        control
    } = useForm<SignUpFormData>({
        /**
         * Resolver integrates Zod schema validation into React Hook Form.
         * Ensures validation logic defined in `SignUpSchema` is applied.
         */
        //@ts-ignore
        resolver: zodResolver(SignUpSchema),
        /**
         * Mode configuration for when validation should occur.
         * - `"onChange"`: Validates fields on every change.
         * - Ensures instant feedback for better UX.
         */
        mode: "onChange",
        defaultValues: {
            firstName: LRFData?.firstName ?? '',
            lastName: LRFData?.lastName ?? '',
            email: LRFData?.email ?? '',
        }
    });

    /**
   * Handles the sign-up process by preparing the payload and dispatching the sign-up action.
   * @param formValues - The user-provided sign-up form data.
   */
    const handleSignup = async (formValues: any): Promise<void> => {
        if (!userNameAvailable) {
            setError('userName', { message: CreateProfileContent.FORM.USERNAME_ALREADY_EXISTS })
            return;
        }
        if (emailNotAvailabilityMessage !== '') {
            setError('email', { message: emailNotAvailabilityMessage })
            return;
        }

        try {
            const payload: SignUpPayload = {
                userType: COMMON_VARS.USER_TYPE.GUEST.toLowerCase(),
                userName: formValues.userName,
                firstName: formValues.firstName,
                lastName: formValues.lastName,
                email: formValues.email,
                password: formValues.password,
                dateOfBirth: formatDateYYYYMMDD(formValues.dateOfBirth),
            };

            if (viewBookingData && viewBookingData?.data?.guestSessionId) {
                payload.guestSessionId = viewBookingData?.data?.guestSessionId
            }

            dispatch(signUp(payload, (data) => {
                if (data?.meta?.status) {
                    dispatch(commonActions.setLRFFlow('otp-verification'))
                } else {
                    Toast("error", data?.meta?.message)
                }
            }));
        } catch (error) {
            console.error(error);
        }
    };


    /**
   * Handles the username or email availability
   * @param type - Availability check is for username or email.
   * @param value - Field value
   */
    const checkAvailability = useDebounce((type: FieldType, value: string) => {
        // Mapping each type to its respective regex validation pattern
        const regexMap: Record<FieldType, RegExp> = {
            userName: REGEX.USER_NAME, // Regular expression for validating username
            email: REGEX.EMAIL, // Regular expression for validating email
        };

        // If the value does not match the regex for the given type, reset the field and availability status
        if (!regexMap[type].test(value)) {
            setValue(type, value.trim()); // Trim and reset the value
            // Reset availability status based on the field type
            if (type === 'userName') setUserNameAvailable(false);
            return;
        }

        // If value length is greater than 0, initiate availability check
        if (value.length >= 5) {
            // Dispatch the availability check action (e.g., check username or email)
            {/*@ts-ignore*/ }
            dispatch(checkUserNameAvailability({ [type]: value }, (data) => {
                if (data?.meta?.status) {
                    // If the availability check is successful, update status and clear any errors
                    if (type === 'userName') {
                        setUserNameAvailable(true);
                        clearErrors('userName');
                    } else if (type === 'email') {
                        setEmailNotAvailabilityMessage('');
                        clearErrors('email');
                    }
                } else {
                    // If the check fails, update availability status and set error message
                    if (type === 'userName') {
                        setUserNameAvailable(false);
                        setError('userName', { message: data?.meta?.message });
                    } else if (type === 'email') {
                        setEmailNotAvailabilityMessage(data?.meta?.message);
                        // setError('email', { message: data?.meta?.message });
                    }
                }
            }));
        } else {
            // If the value is empty, reset availability status
            if (type === 'userName') setUserNameAvailable(false);
            if (type === 'email') setEmailNotAvailabilityMessage('');
        }
    }, COMMON_VARS.DELAY_DEBOUNCE); // Delay debounce value

    // Handle the password strength
    useEffect(() => {
        let passwordStrength = getPasswordStrength(watch("password"));
        const activeCount = Math.max(0, Math.min(3, passwordStrength));
        const strengthClass = STRENGTH_LEVELS[activeCount - 1]?.className || "weak";
        setPasswordStrength(passwordStrength);
        setActiveCount(activeCount);
        setStrengthClass(strengthClass);
    }, [watch("password")])

    return (
        <div className={`flex flex-col gap-[20px] xl:gap-[24px] w-full`}>
            <div className={`bg-white rounded-[12px] w-full`}>
                {LRFFlow === "forgot-password" ?
                    <ForgotPassword CreateProfileContent={CreateProfileContent} />
                    :
                    <>
                        <div className="w-full max-w-[320px] pb-4">
                            <div className="flex rounded-full bg-gray-100 p-1">
                                <button
                                    className={`w-1/2 py-3 px-4 fs-14 !font-medium rounded-full text-center ${isActiveTab === 'create' ? 'bg-primaryColor text-white' : 'bg-whiteColor text-black'}`}
                                    onClick={() => { dispatch(commonActions.setLRFFlow('create')); setIsActiveTab('create') }}
                                >
                                    {CreateProfileContent.FORM.REGISTER}
                                </button>
                                <button
                                    className={`w-1/2 py-3 px-4 fs-14 !font-medium rounded-full text-center  ${isActiveTab === 'login' ? 'bg-primaryColor text-white' : 'bg-whiteColor text-black'}`}
                                    onClick={() => { dispatch(commonActions.setLRFFlow('login')); setIsActiveTab('login') }}
                                >
                                    {CreateProfileContent.FORM.LOGIN}
                                </button>
                            </div>
                        </div>
                        {LRFFlow === "login" ?
                            <LoginForm CreateProfileContent={CreateProfileContent} />
                            :
                            <>
                                {/* <h2 className={`h6 !font-fw600 !mb-[20px] md:!mb-[28px]`}>Create a profile</h2> */}
                                <form onSubmit={handleSubmit(handleSignup)}>
                                    <div className={`InputWrapper relative ${styles.UsernameWrapper}`}>
                                        <label htmlFor="username">{CreateProfileContent.FORM.USERNAME}</label>
                                        <input
                                            className={`!bg-bgColor !fs-16`}
                                            id="username"
                                            placeholder={CreateProfileContent.FORM.ENTER_USERNAME}
                                            type="text"
                                            name="userName"
                                            autoComplete="off"
                                            {...register("userName", {
                                                onChange: (e) => {
                                                    checkAvailability("userName", e.target.value);
                                                },
                                            })}
                                            onPaste={(e) => e.preventDefault()} // disable mouse & keyboard paste
                                            onKeyDown={(e) => {
                                                if (e.key === " " || (e.ctrlKey && (e.key === "v" || e.key === "c"))) {
                                                    e.preventDefault(); // prevent space, Ctrl+V (paste), Ctrl+C (copy)
                                                }
                                            }}
                                        />
                                        {/* Username availability message */}
                                        {userNameAvailable && !errors.userName && (
                                            <p className="username-available">{CreateProfileContent.FORM.USERNAME_AVAILABLE}</p>
                                        )}
                                        {/* error message text */}
                                        {errors?.userName?.message && (
                                            <p className="error-msg">{errors.userName?.message}</p>
                                        )}
                                    </div>
                                    <div className='RowWrap'>
                                        <div className="InputWrapper relative">
                                            <label htmlFor="firstname">{CreateProfileContent.FORM.FIRST_NAME}</label>
                                            <input
                                                className={`!bg-bgColor !fs-16`}
                                                id="firstname"
                                                placeholder={CreateProfileContent.FORM.ENTER_FIRST_NAME}
                                                type="text"
                                                name="firstname"
                                                {...register("firstName", {
                                                    onChange: (e) => {
                                                        setValue("firstName", setFirstCharCapital(e)),
                                                            trigger("firstName")
                                                    }
                                                })}
                                            />
                                            {/* error message text */}
                                            {errors.firstName && (
                                                <p className="error-msg">{errors.firstName?.message}</p>
                                            )}
                                        </div>
                                        <div className="InputWrapper relative">
                                            <label htmlFor="lname">{CreateProfileContent.FORM.LAST_NAME}</label>
                                            <input
                                                className={`!bg-bgColor !fs-16`}
                                                id="lname"
                                                placeholder={CreateProfileContent.FORM.ENTER_LAST_NAME}
                                                type="text"
                                                name="lname"
                                                {...register("lastName", {
                                                    onChange: (e) => {
                                                        setValue("lastName", setFirstCharCapital(e)),
                                                            trigger("lastName")
                                                    }
                                                })}
                                            />
                                            {/* error message text */}
                                            {errors.lastName && (
                                                <p className="error-msg">{errors.lastName?.message}</p>
                                            )}
                                        </div>
                                    </div>
                                    <div className="InputWrapper">
                                        <label htmlFor="email">{CreateProfileContent.FORM.EMAIL}</label>
                                        <input
                                            className={`!bg-bgColor !fs-16`}
                                            id="email"
                                            placeholder={CreateProfileContent.FORM.ENTER_EMAIL}
                                            type="email"
                                            name="email"
                                            {...register("email")}
                                        />
                                        {/* error message text */}
                                        {errors.email && (
                                            <p className="error-msg">{errors.email?.message}</p>
                                        )}
                                    </div>

                                    <div className='DOBDropDown signup-dob mb-4'>
                                        <div className="InputWrapper">
                                            <label htmlFor="dateOfBirth">{CreateProfileContent.FORM.DATE_OF_BIRTH}</label>
                                            <Controller
                                                control={control}
                                                name="dateOfBirth"
                                                render={({ field: { onChange, value } }: any) => (
                                                    <DatePickerItem
                                                        checkInDate={value}
                                                        setCheckInDate={onChange}
                                                        IsDOB={true}
                                                    />
                                                )}
                                            />
                                            {errors.dateOfBirth && (
                                                <p className="error-msg">{errors.dateOfBirth?.message as string}</p>
                                            )}
                                        </div>
                                    </div>
                                    <div className="InputWrapper">
                                        <label htmlFor="password">{CreateProfileContent.FORM.PASSWORD}</label>
                                        <div className={`relative`}>
                                            <input
                                                className={`!bg-bgColor !fs-16`}
                                                id="password"
                                                placeholder="********"
                                                type={showPassword ? 'text' : 'password'}
                                                name="password"
                                                {...register("password", {
                                                    onChange: (e) =>
                                                        getPasswordStrength(e.target.value),
                                                })}
                                            />
                                            <span onClick={() => setShowPassword(prev => !prev)} className={`absolute top-1/2 transition-transform -translate-1/2 right-3 cursor-pointer`}><i className={`!bg-grey85 !w-[18px] !h-[18px] Icon ${showPassword ? 'IconEyeClose' : 'IconEyeOpenPassword'}`}></i></span>
                                        </div>
                                        {/* error message text */}
                                        {errors.password && (
                                            <p className={`error-msg ${passwordStrength > 0 ? '!bottom-[42px]' : ''} !mb-0`}>{errors.password?.message}</p>
                                        )}
                                        {/* Password strength */}
                                        {passwordStrength > 0 && (
                                            <div className='pt-4'><PasswordValidations styles={styles} activeCount={activeCount} strengthClass={strengthClass} /></div>
                                        )}


                                        {/* Password strength end */}
                                    </div>
                                    <div className="InputWrapper">
                                        <Link
                                            target="_blank"
                                            className="!underline !text-[#344054]"
                                            href={Routes.PRIVACY_POLICY}>
                                            Data Privacy Policy
                                        </Link>
                                    </div>
                                    <button className={`w-full SecondaryBtn`} name='submit' type='submit'>{CreateProfileContent.FORM.CREATE_PROFILE}</button>
                                </form>
                            </>
                        }
                    </>
                }
            </div>
        </div>
    )
}

export default CreateProfile