import { useFormik } from "formik";
import * as Yup from "yup";
import Modal from "../../components/Modals";
import Select from "../../components/Select";
import user from "../../assets/images/auth/user.png";
import Datepicker from "../../components/Datepicker";
import { useEffect, useState, useCallback, useRef } from "react";
import { toast } from "react-toastify";
import api from '../../api/axios';
import config from '../../config';
import TagInput from "../../components/TagInput";

interface Props {
    open: boolean;
    onClose: () => void;
    onSave: (data: any) => void;
    data: any;
}

interface Option {
    value: string;
    label: string;
}

const EditStaff = ({ open, onClose, onSave, data }: Props) => {
    const [profile, setProfile] = useState<string | null>(null);
    const [isUsernameChecking, setIsUsernameChecking] = useState(false);
    const [usernameSuggestions, setUsernameSuggestions] = useState<string[]>([]);
    const [showSuggestions, setShowSuggestions] = useState(false);
    const usernameTimeoutRef = useRef<NodeJS.Timeout | null>(null);

    // Tags state for skills
    const [tags, setTags] = useState<string[]>([]);

    // Dynamic data states
    const [branchOptions, setBranchOptions] = useState<Option[]>([]);
    const [deptOptions, setDeptOptions] = useState<Option[]>([]);
    const [roleOptions, setRoleOptions] = useState<Option[]>([]);
    const [shiftOptions, setShiftOptions] = useState<Option[]>([]);
    const [skillOptions, setSkillOptions] = useState<Option[]>([]);
    const [loadingData, setLoadingData] = useState(false);

    // Validation
    const validationSchema = Yup.object({
        staff_name: Yup.string().required("Staff name is required"),
        mobile: Yup.string()
            .required("Mobile number is required")
            .matches(/^[0-9]{10}$/, "Mobile number must be 10 digits"),
        email: Yup.string().email("Invalid email").required("Email is required"),
        branch: Yup.string().required("Branch is required"),
        department: Yup.string().required("Department is required"),
        role: Yup.string().required("Role is required"),
        shift: Yup.string().required("Shift is required"),
        user_name: Yup.string()
            .required("Username is required")
            .min(3, "Username must be at least 3 characters"),
        password: Yup.string().min(6, "Password must be at least 6 characters"),
        salary: Yup.number().required("Salary is required").positive("Salary must be positive"),
    });

    const formik = useFormik({
        enableReinitialize: true,
        initialValues: {
            staff_name: data?.staff_name || "",
            mobile: data?.staff_mobile || "",
            email: data?.staff_email || "",
            branch: data?.branch_ids?.toString() || "",
            department: data?.department_id?.toString() || "",
            role: data?.role_id?.toString() || "",
            shift: data?.shift_id?.toString() || "",
            doj: data?.doj || null,
            salary: data?.salary || "",
            address: data?.address || "",
            user_name: data?.user_name || "",
            password: "",
            pass: data?.password || "",
            profile: null,
        },
        validationSchema,
        onSubmit: async (values) => {
            try {
                const formData = new FormData();
                formData.append('name', values.staff_name);
                formData.append('mobile', values.mobile);
                formData.append('email', values.email);
                formData.append('branch_id', values.branch);
                formData.append('department_id', values.department);
                formData.append('role_id', values.role);
                formData.append('shift_id', values.shift);
                formData.append('doj', values.doj || '');
                formData.append('salary', values.salary);
                formData.append('address', values.address);
                formData.append('user_name', values.user_name);

                if (values.password) {
                    formData.append('password', values.password);
                }

                if (values.profile) {
                    formData.append('image', values.profile);
                }

                // Send skills as JSON string
                formData.append('skills', JSON.stringify(tags));

                const response = await api.post(`/staff/${data?.id}/update`, formData, {
                    headers: { 'Content-Type': 'multipart/form-data' }
                });

                if (response.data.status) {
                    toast.success('Staff updated successfully');
                    onSave(response.data.data);
                    onClose();
                }
            } catch (error: any) {
                if (error.response?.data?.errors) {
                    Object.keys(error.response.data.errors).forEach(key => {
                        formik.setFieldError(key, error.response.data.errors[key][0]);
                    });
                }
                toast.error(error.response?.data?.message || 'Failed to update staff');
            }
        },
    });

    // Check username availability
    const checkUsername = useCallback(async (username: string) => {
        if (!username || username.length < 3) return;

        setIsUsernameChecking(true);
        try {
            const response = await api.post('/staff/username-check', {
                username: username,
                name: formik.values.staff_name,
                mobile: formik.values.mobile,
                staff_id: data?.id
            });

            if (response.data.available) {
                setUsernameSuggestions([]);
                setShowSuggestions(false);
                formik.setFieldError('user_name', '');
            } else {
                setUsernameSuggestions(response.data.suggestions || []);
                setShowSuggestions(true);
                formik.setFieldError('user_name', 'Username is already taken');
            }
        } catch (error) {
            console.error('Username check failed:', error);
        } finally {
            setIsUsernameChecking(false);
        }
    }, [formik.values.staff_name, formik.values.mobile, data?.id]);

    // Handle username change with debounce
    const handleUsernameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const username = e.target.value;
        formik.setFieldValue('user_name', username);
        formik.setFieldTouched('user_name', true);

        if (usernameTimeoutRef.current) {
            clearTimeout(usernameTimeoutRef.current);
        }

        if (username.length >= 3 && username !== data?.user_name) {
            usernameTimeoutRef.current = setTimeout(() => {
                checkUsername(username);
            }, 500);
        } else {
            setShowSuggestions(false);
        }
    };

    // Apply suggestion
    const applySuggestion = (suggestion: string) => {
        formik.setFieldValue('user_name', suggestion);
        setShowSuggestions(false);
        checkUsername(suggestion);
    };

    // Initialize tags from existing staff data
    useEffect(() => {
        if (data?.skills) {
            try {
                // If skills is a JSON string, parse it
                if (typeof data.skills === 'string') {
                    const parsedSkills = JSON.parse(data.skills);
                    setTags(Array.isArray(parsedSkills) ? parsedSkills : []);
                }
                // If skills is already an array
                else if (Array.isArray(data.skills)) {
                    setTags(data.skills);
                }
                // If skills is a comma-separated string
                else if (typeof data.skills === 'string' && data.skills.includes(',')) {
                    setTags(data.skills.split(','));
                }
                // If it's a single string value
                else if (typeof data.skills === 'string' && data.skills) {
                    setTags([data.skills]);
                }
                else {
                    setTags([]);
                }
            } catch (error) {
                console.error('Failed to parse skills data:', error);
                setTags([]);
            }
        } else {
            setTags([]);
        }
    }, [data]);

    // Fetch dynamic data including skill options
    const fetchDynamicData = async () => {
        setLoadingData(true);
        try {
            const [branchResponse, deptResponse, roleResponse,shiftResponse] = await Promise.all([
                api.get('/branch_list'),
                api.get('/department_list'),
                api.get('/role_list'),
                api.get('/shift_times/list'),
            ]);

            if (branchResponse.data.status) {
                setBranchOptions(branchResponse.data.data.map((item: any) => ({
                    value: item.id.toString(),
                    label: item.name
                })));
            }

            if (deptResponse.data.status) {
                setDeptOptions(deptResponse.data.data.map((item: any) => ({
                    value: item.id.toString(),
                    label: item.name
                })));
            }

            if (roleResponse.data.status) {
                setRoleOptions(roleResponse.data.data.map((item: any) => ({
                    value: item.id.toString(),
                    label: item.name
                })));
            }
            if (shiftResponse.data.status) {
                setShiftOptions(shiftResponse.data.data.map((item: any) => ({
                    value: item.id.toString(),
                    label: `${item.name} (${item.start_time}) - ${item.end_time}`
                })));
            }


        } catch (error) {
            console.error('Failed to fetch dynamic data:', error);
            toast.error('Failed to load form data');
        } finally {
            setLoadingData(false);
        }
    };

    useEffect(() => {
        if (open) {
            fetchDynamicData();
        }
    }, [open]);

    useEffect(() => {
        setProfile(data?.staff_pic ? `${config.storageUrl}/${data.staff_pic}` : null);
    }, [data]);

    // Cleanup timeout on unmount
    useEffect(() => {
        return () => {
            if (usernameTimeoutRef.current) {
                clearTimeout(usernameTimeoutRef.current);
            }
        };
    }, []);

    // Safe error handler
    const showError = (field: keyof typeof formik.values) => {
        return formik.touched[field] && formik.errors[field];
    };

    return (
        <Modal
            open={open}
            onClose={onClose}
            title="Edit Staff"
            maxWidth="max-w-3xl"
            footer={
                <>
                    <button onClick={onClose} className="btn btn-outline-danger">
                        Cancel
                    </button>

                    <button
                        onClick={() => formik.handleSubmit()}
                        className="btn btn-primary"
                        disabled={formik.isSubmitting || loadingData}
                    >
                        {formik.isSubmitting ? 'Updating...' : 'Update Staff'}
                    </button>
                </>
            }
        >
            {loadingData ? (
                <div className="flex justify-center items-center py-12">
                    <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div>
                </div>
            ) : (
                <form className="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <div>
                        <label>Staff Name <span className="text-danger">*</span></label>
                        <input
                            name="staff_name"
                            className="form-input w-full"
                            value={formik.values.staff_name}
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                        />
                        {showError("staff_name") && (
                            <div className="text-red-500 text-xs mt-1">
                                {showError("staff_name") as string}
                            </div>
                        )}
                    </div>

                    <div>
                        <label>Mobile <span className="text-danger">*</span></label>
                        <input
                            name="mobile"
                            className="form-input w-full"
                            value={formik.values.mobile}
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                        />
                        {showError("mobile") && (
                            <div className="text-red-500 text-xs mt-1">
                                {showError("mobile") as string}
                            </div>
                        )}
                    </div>

                    <div>
                        <label>Email <span className="text-danger">*</span></label>
                        <input
                            name="email"
                            type="email"
                            className="form-input w-full"
                            value={formik.values.email}
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                        />
                        {showError("email") && (
                            <div className="text-red-500 text-xs mt-1">
                                {showError("email") as string}
                            </div>
                        )}
                    </div>

                    <div>
                        <label>Branch <span className="text-danger">*</span></label>
                        <Select
                            options={branchOptions}
                            value={branchOptions.find(o => o.value === formik.values.branch)}
                            onChange={(val: any) =>
                                formik.setFieldValue("branch", val?.value || "")
                            }
                            placeholder="Select Branch"
                        />
                        {showError("branch") && (
                            <div className="text-red-500 text-xs mt-1">
                                {showError("branch") as string}
                            </div>
                        )}
                    </div>

                    <div>
                        <label>Department <span className="text-danger">*</span></label>
                        <Select
                            options={deptOptions}
                            value={deptOptions.find(o => o.value === formik.values.department)}
                            onChange={(val: any) =>
                                formik.setFieldValue("department", val?.value || "")
                            }
                            placeholder="Select Department"
                        />
                        {showError("department") && (
                            <div className="text-red-500 text-xs mt-1">
                                {showError("department") as string}
                            </div>
                        )}
                    </div>

                    <div>
                        <label>Role <span className="text-danger">*</span></label>
                        <Select
                            options={roleOptions}
                            value={roleOptions.find(o => o.value === formik.values.role)}
                            onChange={(val: any) =>
                                formik.setFieldValue("role", val?.value || "")
                            }
                            placeholder="Select Role"
                        />
                        {showError("role") && (
                            <div className="text-red-500 text-xs mt-1">
                                {showError("role") as string}
                            </div>
                        )}
                    </div>

                    <div>
                        <label>Date of Joining</label>
                        <Datepicker
                            value={formik.values.doj ?? undefined}
                            onChange={(val) =>
                                formik.setFieldValue("doj", val)
                            }
                            placeholder="Pick date"
                        />
                    </div>

                    <div>
                        <label>Salary <span className="text-danger">*</span></label>
                        <input
                            name="salary"
                            type="number"
                            className="form-input w-full"
                            value={formik.values.salary}
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                        />
                        {showError("salary") && (
                            <div className="text-red-500 text-xs mt-1">
                                {showError("salary") as string}
                            </div>
                        )}
                    </div>
                    <div>
                        <label>Shift <span className="text-danger">*</span></label>
                        <Select
                            options={shiftOptions}
                            value={shiftOptions.find(o => o.value === formik.values.shift)}
                            onChange={(val: any) => {
                                formik.setFieldValue("shift", val?.value || "");

                                setTimeout(() => {
                                    formik.setFieldTouched("shift", true);
                                    formik.validateField("shift");
                                }, 0);
                            }}
                            placeholder="Select shift"
                        />
                        {formik.touched.shift && formik.errors.shift && (
                            <p className="text-red-500 text-sm mt-1">{formik.errors.shift as string}</p>
                        )}
                    </div>
                    <div >
                        <label>Address</label>
                        <textarea
                            name="address"
                            className="form-textarea w-full"
                            rows={1}
                            value={formik.values.address}
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                        />
                    </div>

                    <div className="relative">
                        <label>User Name <span className="text-danger">*</span></label>
                        <div className="relative">
                            <input
                                name="user_name"
                                className="form-input w-full pr-10"
                                value={formik.values.user_name}
                                onChange={handleUsernameChange}
                                onBlur={formik.handleBlur}
                            />
                            {isUsernameChecking && (
                                <div className="absolute right-3 top-1/2 transform -translate-y-1/2">
                                    <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-primary"></div>
                                </div>
                            )}
                        </div>
                        {showError("user_name") && (
                            <div className="text-red-500 text-xs mt-1">
                                {showError("user_name") as string}
                            </div>
                        )}

                        {/* Username Suggestions */}
                        {showSuggestions && usernameSuggestions.length > 0 && (
                            <div className="absolute z-10 mt-1 w-full bg-white border rounded-md shadow-lg">
                                <div className="p-2 text-sm text-gray-600 border-b">Suggestions:</div>
                                {usernameSuggestions.map((suggestion, index) => (
                                    <button
                                        key={index}
                                        type="button"
                                        onClick={() => applySuggestion(suggestion)}
                                        className="w-full text-left px-3 py-2 text-sm hover:bg-gray-100 transition-colors"
                                    >
                                        {suggestion}
                                    </button>
                                ))}
                            </div>
                        )}
                    </div>

                    <div>
                        <label>Password (Leave blank to keep unchanged)</label>
                        <input
                            name="password"
                            type="password"
                            className="form-input w-full"
                            value={formik.values.password}
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                        />
                        <p className="text-red-500 text-sm mt-1">Password: {formik.values.pass}</p>
                        {showError("password") && (
                            <div className="text-red-500 text-xs mt-1">
                                {showError("password") as string}
                            </div>
                        )}
                    </div>



                    <div className="md:col-span-2">
                        <label>Skill Tags</label>
                        <TagInput
                            label="Skills"
                            value={tags}
                            onChange={setTags}
                            placeholder="Add skills..."
                        />
                    </div>

                    <div>
                        <label className="block mb-2 font-medium text-black">
                            Staff Image
                        </label>

                        <div className="flex items-center gap-4">
                            <div className="w-20 h-20 rounded-full overflow-hidden border bg-gray-100 flex items-center justify-center">
                                <img
                                    src={profile || user}
                                    alt="profile"
                                    className="w-full h-full object-cover"
                                />
                            </div>

                            <div className="flex gap-2">
                                <label className="cursor-pointer px-4 py-1 bg-primary text-white rounded-md text-sm">
                                    Upload
                                    <input
                                        type="file"
                                        className="hidden"
                                        accept="image/*"
                                        onChange={(e) => {
                                            const file = e.target.files?.[0];
                                            if (file) {
                                                setProfile(URL.createObjectURL(file));
                                                formik.setFieldValue("profile", file);
                                            }
                                        }}
                                    />
                                </label>
                                <button
                                    type="button"
                                    className="px-4 py-1 text-sm bg-red-500 text-white rounded-md"
                                    onClick={() => {
                                        setProfile(null);
                                        formik.setFieldValue("profile", null);
                                    }}
                                >
                                    Remove
                                </button>
                            </div>
                        </div>
                    </div>
                </form>
            )}
        </Modal>
    );
};

export default EditStaff;
