import { useFormik } from "formik";
import * as Yup from "yup";
import { useState, useEffect } from "react";
import Modal from "../../../components/Modals";
import Select from "../../../components/Select";
import IconBox from "../../../components/Icon/IconBox";
import IconChevronLeft from "../../../components/Icon/IconChevronLeft";
import IconChevronRight from "../../../components/Icon/IconChevronRight";
import api from '../../../api/axios';
import { toast } from 'react-toastify';

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

interface Department {
    id: string;
    name: string;
}

interface Staff {
    id: string;
    staff_name: string;
    staff_mobile: string;
}

const AssignAsset = ({ open, onClose, onSave, data }: Props) => {
    //  Move ALL hooks to the top, before any conditional returns
    const [departments, setDepartments] = useState<Department[]>([]);
    const [staffList, setStaffList] = useState<Staff[]>([]);
    const [loadingDepartments, setLoadingDepartments] = useState(false);
    const [loadingStaff, setLoadingStaff] = useState(false);
    const [selectedDepartment, setSelectedDepartment] = useState<string>("");
    const [staffPagination, setStaffPagination] = useState({
        current_page: 1,
        last_page: 1,
        per_page: 10,
        total: 0
    });
    const [staffSearch, setStaffSearch] = useState("");
    const [searchTimeout, setSearchTimeout] = useState<NodeJS.Timeout | null>(null);

    const validationSchema = Yup.object({
        department_id: Yup.string().required("Department is required"),
        staff_id: Yup.string().required("Staff is required"),
    });

    // Formik
    const formik = useFormik({
        initialValues: {
            department_id: data?.department_id || "",
            staff_id: data?.staff_id || "",
        },
        validationSchema,
        enableReinitialize: true,
        onSubmit: async (values) => {
            try {
                const response = await api.post(`/assets/assign/${data.id}`, {
                    department_id: values.department_id,
                    staff_id: values.staff_id
                });

                if (response.data.status === 200) {
                    toast.success("Asset assigned successfully");
                    onSave(response.data.data);
                    onClose();
                    formik.resetForm();
                }
            } catch (error: any) {
                console.error("Error assigning asset:", error);
                toast.error(error.response?.data?.message || "Failed to assign asset");
            }
        },
    });

    // Fetch departments
    useEffect(() => {
        const fetchDepartments = async () => {
            setLoadingDepartments(true);
            try {
                const response = await api.get('/assets/departments/list');
                if (response.data.status === 200) {
                    setDepartments(response.data.data);
                }
            } catch (error) {
                console.error("Error fetching departments:", error);
                toast.error("Failed to fetch departments");
            } finally {
                setLoadingDepartments(false);
            }
        };

        if (open) {
            fetchDepartments();
        }
    }, [open]);

    // Fetch staff based on selected department
    const fetchStaff = async () => {
        if (!selectedDepartment) return;

        setLoadingStaff(true);
        try {
            const params: any = {
                page: staffPagination.current_page,
                per_page: staffPagination.per_page,
            };

            if (staffSearch) {
                params.search = staffSearch;
            }

            const response = await api.get(`/assets/staff/list/${selectedDepartment}`, { params });

            if (response.data.status === 200) {
                setStaffList(response.data.data.items || []);
                setStaffPagination({
                    current_page: response.data.data.current_page || 1,
                    last_page: response.data.data.last_page || 1,
                    per_page: response.data.data.per_page || 10,
                    total: response.data.data.total || 0
                });
            }
        } catch (error) {
            console.error("Error fetching staff:", error);
            toast.error("Failed to fetch staff list");
        } finally {
            setLoadingStaff(false);
        }
    };

    useEffect(() => {
        if (selectedDepartment) {
            fetchStaff();
        } else {
            setStaffList([]);
        }
    }, [selectedDepartment, staffPagination.current_page, staffSearch]);

    // Handle department change
    const handleDepartmentChange = (val: any) => {
        const departmentId = val?.value || "";
        setSelectedDepartment(departmentId);
        formik.setFieldValue("department_id", departmentId);
        formik.setFieldValue("staff_id", "");
        formik.setFieldTouched("department_id", true);
        setStaffPagination(prev => ({ ...prev, current_page: 1 }));
    };

    // Handle staff search with debounce
    const handleStaffSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
        const value = e.target.value;
        setStaffSearch(value);
        setStaffPagination(prev => ({ ...prev, current_page: 1 }));

        if (searchTimeout) {
            clearTimeout(searchTimeout);
        }

        const timeout = setTimeout(() => {}, 500);
        setSearchTimeout(timeout);
    };

    // Handle staff page change
    const handleStaffPageChange = (page: number) => {
        setStaffPagination(prev => ({ ...prev, current_page: page }));
    };

    // Department options
    const departmentOptions = departments.map(dept => ({
        value: dept.id,
        label: dept.name
    }));

    // Staff options
    const staffOptions = staffList.map(staff => ({
        value: staff.id,
        label: `${staff.staff_name} (${staff.staff_mobile})`
    }));

    // ✅ Move the conditional check AFTER all hooks
    // Handle case when data is null/undefined by returning null
    if (!data) {
        return null;
    }

    // ✅ Also handle safety for data.id in onSubmit
    // The onSubmit function already uses data.id, but if data exists here, it should be fine
    // Consider adding a guard in onSubmit as well:
    // if (!data?.id) return;

    return (
        <Modal
            open={open}
            onClose={onClose}
            title="Assign Asset"
            maxWidth="max-w-xl"
            footer={
                <>
                    <button
                        onClick={onClose}
                        className="btn btn-outline-danger"
                        type="button"
                    >
                        Cancel
                    </button>
                    <button
                        onClick={() => formik.handleSubmit()}
                        className="btn btn-primary"
                        type="button"
                        disabled={formik.isSubmitting}
                    >
                        {formik.isSubmitting ? "Assigning..." : "Assign Asset"}
                    </button>
                </>
            }
        >
           <div className="grid grid-cols-12 gap-4">
                <div className="col-span-12 flex gap-2 items-center">
                    <div className='p-4 rounded-xl bg-[#FCE7F3] text-primary'>
                        <IconBox />
                    </div>
                    <div className="flex flex-col">
                        <label className="font-semibold text-lg text-primary mb-0">
                            {data.asset_name}
                        </label>
                        <label className="text-sm text-gray-500 mb-0">
                            {data.category}
                        </label>
                        {data.assigned_to && (
                            <label className="text-xs text-green-600 mt-1">
                                Currently assigned to: {data.assigned_to}
                            </label>
                        )}
                    </div>
                </div>

                <div className="col-span-12 border-b"></div>

                <div className="col-span-12">
                    <form className="grid grid-cols-12 gap-4">
                        <div className="col-span-12">
                            <label className="block text-sm font-medium text-gray-700 mb-1">
                                Department <span className="text-red-500">*</span>
                            </label>
                            <Select
                                options={departmentOptions}
                                isLoading={loadingDepartments}
                                placeholder="Select Department"
                                value={departmentOptions.find(o => o.value === formik.values.department_id)}
                                onChange={handleDepartmentChange}
                            />
                            {formik.touched.department_id && formik.errors.department_id && (
                                <p className="text-red-500 text-sm mt-1">{formik.errors.department_id as string}</p>
                            )}
                        </div>

                        <div className="col-span-12">
                            <label className="block text-sm font-medium text-gray-700 mb-1">
                                Staff <span className="text-red-500">*</span>
                            </label>

                            <Select
                                options={staffOptions}
                                isLoading={loadingStaff}
                                placeholder={selectedDepartment ? "Select Staff" : "Please select department first"}
                                value={staffOptions.find(o => o.value === formik.values.staff_id)}

                                onChange={(val: any) => {
                                    formik.setFieldValue("staff_id", val?.value || "");

                                    setTimeout(() => {
                                        formik.setFieldTouched("staff_id", true);
                                        formik.validateField("staff_id");
                                    }, 0);
                                }}
                                isDisabled={!selectedDepartment}
                            />
                            {formik.touched.staff_id && formik.errors.staff_id && (
                                <p className="text-red-500 text-sm mt-1">{formik.errors.staff_id as string}</p>
                            )}


                        </div>
                    </form>
                </div>
            </div>
        </Modal>
    );
};

export default AssignAsset;
