import React, { useEffect, useState } from 'react'
import AdminDashboard from '../AdminDashboard/AdminDashboard'
import { useLocation, useNavigate } from 'react-router-dom'
import { Message } from '../../../components/message'
import { BsChevronLeft } from 'react-icons/bs'
import { GetLocalStorage } from '../../../Utils/Utils'
import { getRolesAllListData, getRolesListData, submitAdminUserData, updateAdminUserData } from '../../../services/api/admin'
import Select from 'react-select';
import { checkPattern, checkPatternWithSpecialCharacter, checkValidEmail, checkValidMobile, customStylesAcc, invalidCharactersRegex, selectTheme } from '../../../Utils/common'
import { UploadIcon } from '../AdminIcon'
import BeatLoader from 'react-spinners/BeatLoader';
import { stateDistrict, checkEmailMobile } from '../../../services/api/auth'

const AddAdminUser = () => {
    const navigate = useNavigate()
    const location = useLocation()
    const token = GetLocalStorage("userInfo")
    const [apiMessage, setApiMessage] = useState({ type: '', message: '' });
    const [districtList, setDistrictList] = useState([]);
    const [districtId, setDistrictId] = useState('');
    const [roleList, setRoleList] = useState([]);
    const [roleId, setRoleId] = useState('');
    const [titleId, setTitleId] = useState('');
    const [image, setImage] = useState();
    const [imageError, setImageError] = useState();
    const [userId, setUserId] = useState('')
    const [file, setFile] = useState();
    const [loading, setLoading] = useState(false);
    const [existingMobileNo, setExistingMobileNo] = useState()
    const [status, setStatus] = useState()
    const [formData, setFormData] = useState({
        name: '',
        userName: '',
        email: '',
        mobileNo: '',
        address:'',
        district: ''
    })
    const [error, setError] = useState({
        name: '',
        userName: '',
        email: '',
        mobileNo: '',
        image: '',
        roleId: '',
        title: '',
        address: '',
        district: ''
    })

    const listOfTitle = [
        { value: '1', label: 'Mr.' },
        { value: '2', label: 'Mrs.' },
        { value: '3', label: 'Miss' },
        { value: '4', label: 'Ms' },
        { value: '5', label: 'Dr' },
    ]

    useEffect(() => {
        if (!token) {
            navigate("/")
        } else {
            if (location?.state && location?.pathname == "/admin/admin-users/update") {
                editAdminUser(location?.state)
            }
        }
    }, [location?.state])

    useEffect(() => {
        getRolesList();
        getDistrictList();
    }, []);

    const getRolesList = async () => {
        try {
            const RolesData = await getRolesAllListData()
            const data = RolesData?.data?.map(i => ({
                label: i?.title, value: i?.id
            }))
            setRoleList(data)
        } catch (err) {
            setApiMessage({ type: 'error', message: err?.message });
        }
    }

    const getDistrictList = async () => {
        try {
            const districtData = await stateDistrict()
            const data = districtData?.data?.data?.map((district) => ({
                label: district?.name_en,
                value: district?.id,
            }));
            setDistrictList(data)
        } catch (err) {
            setApiMessage({ type: 'error', message: err?.message });
        }
    }

    const handleInputChange = async (e) => {
        const { name, value } = e.target
        const cursorPosition = e.target.selectionStart;
        // //console.log(name, value)
        if (name == 'name') {
            if (await checkPattern(value) == false) {
                e.preventDefault()
                return;
            }
        } else if (name == 'userName') {
            // Check for spaces in the userName
            if (/\s/.test(value)) {
                e.preventDefault();
                return;
            } else if (await checkPatternWithSpecialCharacter(value) == false) {
                e.preventDefault();
                return;
            }
        } else if (name == 'mobileNo') {
            if (!/^\d*$/.test(value)) {
                return;

            }
            if (value.length === 1 && /^[0-5]$/.test(value)) {
                return;
            }
            // if (value.length == 10) {
            //     // Setting mobile no here because it is causing delay for the 10th digit to set
            //     setFormData(prevState => ({
            //         ...prevState,
            //         [name]: value
            //     }));
            // }
        }

        setFormData(prevState => ({
            ...prevState,
            [name]: value
        }));

        setTimeout(() => {
            e.target.setSelectionRange(cursorPosition, cursorPosition);
        }, 0);

        validateOnChangeHandle(name, value);
    }

    const validateOnChangeHandle = async (name, value) => {
        let formErrors = error;
        switch (name) {
            case 'name':
                if (!value?.trim()) {
                    formErrors.name = 'Please enter name';
                } else {
                    formErrors.name = ''
                }
                break;
            case 'userName':
                if (!value?.trim()) {
                    formErrors.userName = 'Please Enter username';
                } else {
                    formErrors.userName = ''
                }
                break;
            case 'email':
                if (!value?.trim()) {
                    formErrors.email = 'Please enter email';
                } else {
                    formErrors.email = ''
                }
                break;
            case 'mobileNo':
                if (!value?.trim()) {
                    formErrors.mobileNo = 'Please enter mobile number';
                } else {
                    formErrors.mobileNo = ''
                }
                break;
            case 'address':
                if (!value?.trim()) {
                    formErrors.address = 'Please enter address';
                } else {
                    formErrors.address = ''
                }
                break;
        }
        setError(formErrors);
        return formErrors;
    }

    const validateOnBlurHandle = async (e) => {
        const { name, value } = e?.target;

        // Create a copy of the current errors state
        let formErrors = { ...error };

        if (name === 'name') {
            if (!value.trim()) {
                formErrors.name = 'Please enter user name';
            } else {
                formErrors.name = '';
            }
        } else if (name === 'userName') {
            if (!value.trim()) {
                formErrors.userName = 'Please enter user username';
            } else {
                formErrors.userName = '';
            }
        } else if (name === 'email') {
            if (!value.trim()) {
                formErrors.email = 'Please enter user email';
            } else {
                const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
                if (!emailPattern.test(value)) {
                    formErrors.email = 'Please enter a valid email';
                } else {
                    formErrors.email = '';
                }
            }
        } else if (name === 'mobileNo') {
            if (!value.trim()) {
                formErrors.mobileNo = 'Please enter mobile number';
            } else {
                // Indian mobile number validation: starts with 6,7,8 or 9, exactly 10 digits
                const mobilePattern = /^[6789]\d{9}$/;
                if (!mobilePattern.test(value)) {
                    formErrors.mobileNo = 'Please enter a valid mobile number';
                } else {
                    formErrors.mobileNo = '';
                }
            }
        } else if (name === 'address') {
            if (!value.trim()) {
                formErrors.address = 'Please enter the user address';
            } else {
                formErrors.address = '';
            }
        } 

        // Update the error state
        setError(formErrors);
        setLoading(false);  // Hide loader
    };

    const validateRole = () => {
        let formErrors = { ...error };
        if (!roleId) {
            formErrors.roleId = 'Please select user role'
        } else {
            formErrors.catId = '';
        }
        setError(formErrors);
    }

    const validateTitleOnBlur = () => {
        let formErrors = { ...error };
        if (!titleId) {
            formErrors.title = 'Please select title'
        } else {
            formErrors.title = '';
        }
        setError(formErrors);
    }

    const validateDistrict = () => {
        let formErrors = { ...error };
        if (!districtId) {
            formErrors.district = 'Please select district'
        } else {
            formErrors.district = '';
        }
        setError(formErrors);
    }

    const handleFileChange = (e) => {
        const file = e?.target?.files?.[0];
        if (file) {
            if (file.type.startsWith('image/')) {
                setImage(file);
                setFile(URL.createObjectURL(e.target.files[0]));
                setImageError('');
            } else {
                setImage(null);
                setFile('')
                setImageError('Please upload image.');
                e.target.value = '';
            }
        }
    };

    const editAdminUser = (data) => {
        //console.log("data ::::" + JSON.stringify(data, null, 2))
        setFormData({
            name: data?.name,
            userName: data?.username,
            email: data?.email,
            mobileNo: data?.mobile_number,
            address:data?.address,
        })
        setUserId(data.id)
        setImage(data?.upload_photo)
        setRoleId(data?.role_id)
        setTitleId(data?.title)
        setDistrictId(data?.district)
        setExistingMobileNo(data?.mobile_number)
        setStatus(data?.status)
    }

    const handleSubmit = async (e) => {
        try {
            e.preventDefault();
            setLoading(true);  // Show loader
            let validationErrors = { ...error };
            await Promise.all(Object.keys(formData).map(async (key) => {
                const value = formData[key];
                const errors = await validateOnChangeHandle(key, value);
                if (!roleId) {
                    error.roleId = " Please select role"
                }
                if (!titleId) {
                    error.title = " Please select title"
                }
                if (!districtId ) {
                    error.district = " Please select district"
                }
                if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(formData.email)) {
                    error.email = 'Please enter  valid email';
                }
                if (!image) {
                    setImageError('Please upload image.');
                }
                validationErrors = { ...validationErrors, ...errors };

            }));
            setError(validationErrors);
            if (Object.values(validationErrors).some(error => error !== '')) {
                setLoading(false);  // Hide loader
                return;
            }

            const AdminUserData = new FormData();
            AdminUserData.append("mobile_number", formData.mobileNo)
            // const emailMobileExists = await checkEmailMobile(AdminUserData);
            // //console.log(emailMobileExists)0
            // if (emailMobileExists.status === 200) {
            //     let formErrors = error;
            //     formErrors.mobileNo = emailMobileExists.message;
            //     setError(formErrors);
            //     setLoading(false);  // Hide loader
            //     return;
            // }
            AdminUserData.append("name", formData.name)
            AdminUserData.append("username", formData.userName)
            AdminUserData.append("email", formData.email)
            AdminUserData.append("role_id", roleId)
            AdminUserData.append("upload_photo", image?.name ? image : "")
            AdminUserData.append("title", titleId)
            AdminUserData.append("district", districtId ? districtId : "")
            AdminUserData.append("address", formData.address)
            const userData = await submitAdminUserData(AdminUserData);
            // If API returns validation errors
            if (userData?.status !== 200 && userData?.success === false) {
                // Map server-side validation errors to your form errors
                const apiErrors = userData.data;
                let newErrors = { ...validationErrors };
                if (apiErrors.email) {
                    newErrors.email = apiErrors.email[0]; // Example: 'Email is already taken'
                }
                if (apiErrors.mobile_number) {
                    newErrors.mobileNo = apiErrors.mobile_number[0]; // Example: 'Mobile number is already taken'
                }
                if (apiErrors.username) {
                    newErrors.userName = apiErrors.username[0]; // Example: 'Mobile number is already taken'
                }
                setError(newErrors);
                setLoading(false);  // Hide loader
                return;
            }
            if (userData?.status == 200) {
                setLoading(false);  // Hide loader
                navigate("/admin/admin-users", { state: { message: userData.message } })
            }else{
                setLoading(false);
                setApiMessage({ type: 'error', message: userData.message })
            }
        } catch (err) {
            setLoading(false);
            setApiMessage({ type: 'error', message: err.message })
        }
    }

    const updateFields = async (e) => {
        try {
            e.preventDefault();
            //console.log("sdjsjdh", roleId)
            let validationErrors = { ...error };
            await Promise.all(Object.keys(formData).map(async (key) => {
                const value = formData[key];
                const errors = await validateOnChangeHandle(key, value);
                if (!roleId) {
                    error.roleId = " Please Select user Role"
                }
                if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(formData.email)) {
                    error.email = 'Please Enter the valid user Email';
                }
                if (!titleId) {
                    error.title = " Please Select user Title"
                }
                if (!districtId ) {
                    error.district = " Please Select District"
                }
                if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(formData.email)) {
                    error.email = 'Please Enter the valid user Email';
                }
                if (!image) {
                    error.image = 'Please upload image'
                }
                validationErrors = { ...validationErrors, ...errors };

            }));
            setError(validationErrors);
            setLoading(false);  // Hide loader
            if (Object.values(validationErrors).some(error => error !== '')) {
                return;
            }


            const AdminUserData = new FormData();
            AdminUserData.append("mobile_number", formData.mobileNo)
            if (formData.mobileNo != existingMobileNo) {
                const emailMobileExists = await checkEmailMobile(AdminUserData);
                //console.log(emailMobileExists)
                if (emailMobileExists.status === 200) {
                    let formErrors = error;
                    formErrors.mobileNo = emailMobileExists.message;
                    setError(formErrors);
                    setLoading(false);  // Hide loader
                    return;
                }
            }
            AdminUserData.append("name", formData.name)
            AdminUserData.append("username", formData.userName)
            AdminUserData.append("id", userId)
            AdminUserData.append("email", formData.email)
            AdminUserData.append("role_id", roleId)
            AdminUserData.append("upload_photo", image?.name ? image : "")
            AdminUserData.append("title", titleId)
            AdminUserData.append("district", districtId ? districtId : "")
            AdminUserData.append("address", formData.address)
            AdminUserData.append("status", status)
            const userData = await updateAdminUserData(AdminUserData)
            if (userData?.status == 200) {
                navigate("/admin/admin-users", { state: { message: userData.message } })
            } else {
                setApiMessage({ type: 'error', message: userData.message })
            }
        } catch (err) {
            setApiMessage({ type: 'error', message: err.message })
        }
    }

    return (
        <AdminDashboard>
            <div className='aod-outer'>
                {apiMessage && (<Message apiMessage={apiMessage} setApiMessage={setApiMessage}></Message>)}
                <div className='ap-breadcrumb pt-2 pb-2 mb-2 adm-breadcrumb'>
                    <div>
                        <b onClick={() => navigate("/admin/")}>Home  /</b><span> Admin Users/{userId ? "edit" : "add"}</span>
                    </div>
                </div>
                <div className="aod-inner">
                    <div className={userId ? "aod-bottom" : "aod-bottom"}>
                        <div className="aod-head text-center adm-head"><button onClick={() => navigate("/admin/admin-users")}><BsChevronLeft /> Back</button>{userId ? "Update" : "Add"} Admin</div>
                        {loading && (
                            <div className="loader">
                                <BeatLoader color="#36d7b7" loading={loading} size={15} />
                            </div>
                        )}
                        <form>
                            <div className="row py-4">
                                <div className="col-md-4 aod-resp-tab">
                                    <div className='suf-input-box aod-form-input mb-2'>
                                        <label htmlFor="roles" className='mb-1 w-100'><span className="en-lable">Select Role</span>
                                        </label>

                                        <Select
                                            styles={customStylesAcc}
                                            theme={selectTheme}
                                            components={{
                                                IndicatorSeparator: () => null
                                            }}
                                            className="my-select selectpicker"
                                            classNamePrefix="ad-menu_open_select_class"
                                            aria-label="Default select example"
                                            name="title"
                                            value={listOfTitle?.find(option => option.value === titleId) || null}
                                            options={listOfTitle}
                                            onBlur={(e) => validateTitleOnBlur}
                                            onChange={(selectedOption) => {
                                                setTitleId(selectedOption.value)
                                                error.title = ''
                                            }}
                                            placeholder="Select Title"
                                        />
                                        {error.title && <p className='validate-error'>{error.title}</p>}
                                    </div>
                                </div>

                                <div className="col-md-4 aod-resp-tab">
                                    <div className='suf-input-box aod-form-input mb-2'>

                                        <label className='mb-1 w-100'>
                                            Name
                                        </label>
                                        <input
                                            className='w-100'
                                            maxLength={100}
                                            name='name'
                                            placeholder='Enter User Name '
                                            type="text"
                                            onChange={(e) => handleInputChange(e)} // Use onChange for real-time validation
                                            onBlur={(e) => validateOnBlurHandle(e)}
                                            value={formData.name}
                                        />
                                        {error.name && <p className='validate-error'>{error.name}</p>}

                                    </div>
                                </div>
                                <div className="col-md-4 aod-resp-tab">
                                    <div className='suf-input-box aod-form-input mb-2'>

                                        <label className='mb-1 w-100'>
                                            User Name
                                        </label>
                                        <input
                                            className='w-100'
                                            maxLength={100}
                                            name='userName'
                                            placeholder='Enter User Name '
                                            type="text"
                                            onChange={(e) => handleInputChange(e)}
                                            onBlur={(e) => validateOnBlurHandle(e)} // Use onChange for real-time validation
                                            value={formData.userName}
                                            disabled={userId ? true : false}
                                        />
                                        {error.userName && <p className='validate-error'>{error.userName}</p>}

                                    </div>
                                </div>
                                <div className="col-md-4 aod-resp-tab">
                                    <div className='suf-input-box aod-form-input mb-2'>

                                        <label className='mb-1 w-100'>
                                           Address
                                        </label>
                                        <input
                                            className='w-100'
                                            maxLength={100}
                                            name='address'
                                            placeholder='Enter User Address '
                                            type="text"
                                            onChange={(e) => {
                                                if(!invalidCharactersRegex.test(e?.target?.value)){
                                                    handleInputChange(e)
                                                }
                                            }}
                                            onBlur={(e) => validateOnBlurHandle(e)} // Use onChange for real-time validation
                                            value={formData.address}
                                        />
                                        {error.address && <p className='validate-error'>{error.address}</p>}

                                    </div>
                                </div>
                                <div className="col-md-4 aod-resp-tab">
                                    <div className='suf-input-box aod-form-input mb-2'>

                                        <label className='mb-1 w-100'>
                                            Email
                                        </label>
                                        <input
                                            className='w-100'
                                            maxLength={100}
                                            name='email'
                                            placeholder='Enter User Email '
                                            type="text"
                                            onChange={(e) => handleInputChange(e)}
                                            onBlur={(e) => validateOnBlurHandle(e)} // Use onChange for real-time validation
                                            value={formData.email}
                                        />
                                        {error.email && <p className='validate-error'>{error.email}</p>}

                                    </div>
                                </div>
                                <div className="col-md-4 aod-resp-tab">
                                    <div className='suf-input-box aod-form-input mb-2'>

                                        <label className='mb-1 w-100'>
                                            Mobile number
                                        </label>
                                        <input
                                            className='w-100'
                                            maxLength={10}
                                            name='mobileNo'
                                            placeholder='Enter User Mobile Number '
                                            type="text"
                                            onChange={(e) => handleInputChange(e)}
                                            onBlur={(e) => validateOnBlurHandle(e)} // Use onChange for real-time validation
                                            value={formData.mobileNo}
                                        />

                                        {error.mobileNo && <p className='validate-error'>{error.mobileNo}</p>}

                                    </div>
                                </div>

                                <div className="col-md-4 aod-resp-tab">
                                    <div className='suf-input-box aod-form-input mb-2'>
                                        <label htmlFor="roles" className='mb-1 w-100'><span className="en-lable">Select Role</span>
                                        </label>

                                        <Select
                                            styles={customStylesAcc}
                                            theme={selectTheme}
                                            components={{
                                                IndicatorSeparator: () => null
                                            }}
                                            className="my-select selectpicker"
                                            classNamePrefix="ad-menu_open_select_class"
                                            aria-label="Default select example"
                                            name="role"
                                            value={roleList?.find(option => option.value === roleId) || null}
                                            options={roleList}
                                            onBlur={validateRole}
                                            onChange={(selectedOption) => {
                                                setRoleId(selectedOption.value)
                                                error.roleId = ''
                                               
                                                    error.district = ''
                                                    setDistrictId('')
                                                
                                            }}
                                            placeholder="Select Role"
                                        />
                                        {error.roleId && <p className='validate-error'>{error.roleId}</p>}
                                    </div>
                                </div>
                             
                                
                                    <div className="col-md-4 aod-resp-tab">
                                        <div className='suf-input-box aod-form-input mb-2'>
                                            <label htmlFor="roles" className='mb-1 w-100'><span className="en-lable">Select District</span>
                                            </label>

                                            <Select
                                                styles={customStylesAcc}
                                                theme={selectTheme}
                                                components={{
                                                    IndicatorSeparator: () => null
                                                }}
                                                className="my-select selectpicker"
                                                classNamePrefix="ad-menu_open_select_class"
                                                aria-label="Default select example"
                                                name="role"
                                                value={districtList?.find(option => option.value == districtId) || null}
                                                options={districtList}
                                                onBlur={validateDistrict}
                                                onChange={(selectedOption) => {
                                                    setDistrictId(selectedOption.value)
                                                    error.district = ''
                                                }}// Use onChange for real-time validation
                                                placeholder="Select District"
                                            />
                                            {error.district && <p className='validate-error'>{error.district}</p>}
                                        </div>
                                    </div>
                                {/* <div className="col-md-4 aod-resp-tab d-flex  align-items-top">
                                    <div className='suf-input-box aod-form-input mb-2 w-100'>
                                        <label className='mb-1 w-100'>
                                            Image
                                        </label>
                                        <input type="file" name="partsuploadfile" id="profileimg" className="w-100 ad-cat-input-field-image" accept="image/*" onKeyUp={() => handleKeyUpLoginDetails("img")} onChange={(e) => handleFileChange(e)} />
                                        <label htmlFor="profileimg" className="ad-cat-input-upload-image p-0">
                                            <p className="ad-cat-text-upload-image">
                                                <span><UploadIcon /></span>  {
                                                    typeof image === 'string' ? (
                                                        <p className="mb-0">{image}</p>
                                                    ) : (
                                                        image?.name ? (
                                                            <p className="mb-0 fw-semibold">{image?.name}</p>
                                                        ) : (
                                                            "Choose Category Image"
                                                        )
                                                    )
                                                }
                                            </p>
                                        </label>
                                        {

                                            imageError ? <p className="validate-error">{imageError}</p> : ""


                                        }

                                    </div>

                                </div> */}
                                <div className="col-md-4 aod-resp-tab d-flex  align-items-top">
                                    <div className='suf-input-box aod-form-input mb-2 w-100'>
                                        <label className='mb-1 w-100'>
                                            Image {error.image}
                                        </label>
                                        <input maxLength={60} type="file" name="partsuploadfile" id="profileimg" className="w-100 ad-cat-input-field-image" accept="image/*" onChange={(e) => handleFileChange(e)} />
                                        <label htmlFor="profileimg" className="ad-cat-input-upload-image p-0">
                                            <p className="ad-cat-text-upload-image">
                                                <span><UploadIcon /></span> {
                                                    typeof image === 'string' ? (
                                                        <span className="mb-0 border-0 bg-transparent">{image.split('\\').pop().split('/').pop()}</span>
                                                    ) : (
                                                        image?.name ? (
                                                            <span className="mb-0 fw-semibold border-0 bg-transparent">{image?.name}</span>
                                                        ) : (
                                                            "Choose Image"
                                                        )
                                                    )
                                                }
                                            </p>
                                        </label>
                                        {
                                            imageError ? <p className="validate-error">{imageError}</p> : ""
                                        }


                                    </div>
                                    {file &&
                                        <div id="img_preview" className="pt-4">
                                            <img className="ms-1 uplaoed_img_preview" src={file} alt="" />
                                        </div>

                                    }
                                </div>
                                <div className="row ad-cat-row">
                                    <div className=" update-btns-block mt-3">
                                        {
                                            userId ?
                                                <>

                                                    <button onClick={(e) => updateFields(e)}>
                                                        Update
                                                    </button>
                                                </> :

                                                <button onClick={(e) => handleSubmit(e)}>
                                                    Submit
                                                </button>

                                        }
                                    </div>

                                </div>
                            </div>
                        </form>

                    </div>
                </div>
            </div>
        </AdminDashboard>
    )
}

export default AddAdminUser;
