import { useFormik } from "formik";
import * as Yup from "yup";
import Modal from "../../components/Modals";
import Select from "../../components/Select";
import Datepicker from "../../components/Datepicker";
import IconMail from "../../components/Icon/IconMail";
import IconPhone from "../../components/Icon/IconPhone";
import IconEye from "../../components/Icon/IconEye";
import IconEyeOff from "../../components/Icon/IconEyeOff";
import api from '../../api/axios';
import { toast } from 'react-toastify';
import { useState, useEffect, useCallback } from 'react';

interface Props {
    open: boolean;
    onClose: () => void;
    onSave: (data: any) => Promise<boolean>;
    data: any;
}
type OptionType = {
  value: string;
  label: string;
};
const ConvertStudent = ({ open, onClose, onSave, data }: Props) => {
    const [courseOptions, setCourseOptions] = useState<OptionType[]>([]);
    const [batchOptions, setBatchOptions] = useState<OptionType[]>([]);
    const [loading, setLoading] = useState(false);
    const [showPassword, setShowPassword] = useState(false);
    const [usernameChecking, setUsernameChecking] = useState(false);
    const [usernameAvailable, setUsernameAvailable] = useState<boolean | null>(null);
    const [usernameSuggestions, setUsernameSuggestions] = useState<string[]>([]);

    // Validation Schema - Define first
    const validationSchema = Yup.object({
        dob: Yup.date().required("Date of birth is required"),
        enrollment_date: Yup.date().required("Enrollment date is required"),
        address: Yup.string().required("Address is required"),
        emergency_name: Yup.string().required("Emergency contact name is required"),
        emergency_phone: Yup.string()
            .required("Emergency phone is required")
            .matches(/^[0-9]{10}$/, "Invalid phone number (must be 10 digits)"),
        course_id: Yup.number().required("Course is required"),
        batch_id: Yup.number().required("Batch/Class is required"),
        total_fees: Yup.number()
            .typeError("Must be a number")
            .required("Total fees is required")
            .min(0, "Total fees cannot be negative"),
        fees_paid: Yup.number()
            .typeError("Must be a number")
            .min(0, "Initial payment cannot be negative")
            .test(
                "less-than-total",
                "Initial payment cannot exceed total fees",
                function (value) {
                    const { total_fees } = this.parent;
                    return !value || value <= total_fees;
                }
            ),
        user_name: Yup.string()
            .required("Username is required")
            .min(3, "Username must be at least 3 characters")
            .test("username-available", "Username is already taken", function(value) {
                return usernameAvailable !== false;
            }),
        password: Yup.string()
            .required("Password is required")
            .min(6, "Password must be at least 6 characters"),
        notes: Yup.string().nullable(),
    });

    // Formik initialization - Moved BEFORE useEffect hooks
    const formik = useFormik({
        enableReinitialize: true,
        initialValues: {
            dob: data?.dob || "",
            enrollment_date: data?.enrollment_date || new Date().toISOString().split('T')[0],
            address: data?.address || "",
            emergency_name: data?.emergency_name || "",
            emergency_phone: data?.emergency_phone || "",
            course_id: data?.course_id || "",
            batch_id: data?.batch_id || "",
            total_fees: data?.total_fees || "",
            fees_paid: data?.fees_paid || "0",
            user_name: data?.user_name || "",
            password: data?.password || "",
            notes: data?.notes || "",
        },
        validationSchema,
        onSubmit: async (values) => {
            if (usernameAvailable === false) {
                toast.error('Please choose a different username');
                return;
            }

            setLoading(true);
            try {
                const submitData = {
                    ...values,
                    lead_id: data?.id,
                    fees_paid: Number(values.fees_paid) || 0,
                    total_fees: Number(values.total_fees),
                };

                const success = await onSave(submitData);
                if (success) {
                    formik.resetForm();
                    onClose();
                }
            } finally {
                setLoading(false);
            }
        },
    });

    // Check username availability - Define after formik
    const checkUsername = useCallback(async (username: string) => {
        if (!username || username.length < 3) {
            setUsernameAvailable(null);
            setUsernameSuggestions([]);
            return;
        }

        setUsernameChecking(true);
        try {
            const response = await api.post('/lead/username-check', {
                username: username,
                name: data?.lead_name || data?.name,
                mobile: data?.lead_mobile || data?.phone
            });

            if (response.data.available) {
                setUsernameAvailable(true);
                setUsernameSuggestions([]);
            } else {
                setUsernameAvailable(false);
                setUsernameSuggestions(response.data.suggestions || []);
            }
        } catch (error) {
            console.error('Error checking username:', error);
            setUsernameAvailable(null);
        } finally {
            setUsernameChecking(false);
        }
    }, [data]);

    // Fetch courses
    useEffect(() => {
        const fetchCourses = async () => {
            try {
                const response = await api.get('/course/lists');
                if (response.data.status === true || response.data.status === 200) {
                    const courseData = response.data.data?.data || response.data.data || [];
                    const options = courseData.map((course: any) => ({
                        value: course.id,
                        label: course.course_name || course.name
                    }));
                    setCourseOptions(options);
                }
            } catch (error) {
                console.error('Error fetching courses:', error);
                toast.error('Failed to load courses');
            }
        };

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

    // Fetch batches based on selected course
    useEffect(() => {
        const fetchBatches = async () => {
            const courseId = formik.values.course_id;
            if (!courseId) {
                setBatchOptions([]);
                return;
            }

            try {
                const response = await api.get(`/batch/list-by-course/${courseId}`);
                if (response.data.status === true || response.data.status === 200) {
                    const batchData = response.data.data?.data || response.data.data || [];
                    const options = batchData.map((batch: any) => ({
                        value: batch.id,
                        label: `${batch.batch_name || batch.name} (${batch.batch_timing || ''})`
                    }));
                    setBatchOptions(options);
                }
            } catch (error) {
                console.error('Error fetching batches:', error);
                toast.error('Failed to load batches');
            }
        };

        if (open && formik.values.course_id) {
            fetchBatches();
        }
    }, [open, formik.values.course_id]);

    const remaining = Math.max(0, Number(formik.values.total_fees || 0) - Number(formik.values.fees_paid || 0));

    const applySuggestion = (suggestion: string) => {
        formik.setFieldValue("user_name", suggestion);
        checkUsername(suggestion);
    };

    if (!data) return null;

    return (
        <Modal
            open={open}
            onClose={() => {
                formik.resetForm();
                setUsernameAvailable(null);
                setUsernameSuggestions([]);
                onClose();
            }}
            title="Convert to Student"
            maxWidth="max-w-2xl"
            footer={
                <>
                    <button
                        onClick={() => {
                            formik.resetForm();
                            onClose();
                        }}
                        className="btn btn-outline-danger"
                        type="button"
                        disabled={loading}
                    >
                        Cancel
                    </button>

                    <button
                        onClick={() => formik.handleSubmit()}
                        disabled={!formik.isValid || loading || usernameAvailable === false}
                        className="btn btn-primary disabled:opacity-50"
                        type="button"
                    >
                        {loading ? "Converting..." : "Convert to Student"}
                    </button>
                </>
            }
        >
            <form className="space-y-4">
                {/* Lead Information Display */}
                <div className="bg-gray-100 rounded p-3">
                    <label className="text-black font-semibold text-base">{data?.lead_name || data?.name}</label>
                    <div className="flex justify-between mt-1 flex-wrap gap-2">
                        <span className="flex items-center justify-start gap-2">
                            <IconMail className="w-4 h-4"/>
                            {data?.lead_email || data?.email || "-"}
                        </span>
                        <span className="flex items-center justify-start gap-2">
                            <IconPhone className="w-4 h-4"/>
                            {data?.lead_mobile || data?.phone || "-"}
                        </span>
                    </div>
                </div>

                <div className="grid grid-cols-2 gap-3">
                    <div>
                        <label className="block text-md font-medium text-gray-900 mb-1">
                            Date of Birth <span className='text-danger'>*</span>
                        </label>
                        <Datepicker
                            value={formik.values.dob}
                            onChange={(val) => {
                                formik.setFieldValue("dob", val);
                                formik.setFieldTouched("dob", true);
                            }}
                            placeholder="Pick date"
                            maxDate={new Date()}
                        />
                        {formik.touched.dob && formik.errors.dob && (
                            <p className="text-red-500 text-xs mt-1">{formik.errors.dob as string}</p>
                        )}
                    </div>

                    <div>
                        <label className="block text-md font-medium text-gray-900 mb-1">
                            Enrollment Date <span className='text-danger'>*</span>
                        </label>
                        <Datepicker
                            value={formik.values.enrollment_date}
                            onChange={(val) => {
                                formik.setFieldValue("enrollment_date", val);
                                formik.setFieldTouched("enrollment_date", true);
                            }}
                            placeholder="Pick date"
                        />
                        {formik.touched.enrollment_date && formik.errors.enrollment_date && (
                            <p className="text-red-500 text-xs mt-1">{formik.errors.enrollment_date as string}</p>
                        )}
                    </div>
                </div>

                <div>
                    <label className="block text-md font-medium text-gray-900 mb-1">
                        Address <span className='text-danger'>*</span>
                    </label>
                    <textarea
                        name="address"
                        rows={2}
                        value={formik.values.address}
                        onChange={formik.handleChange}
                        onBlur={formik.handleBlur}
                        className="form-textarea w-full"
                        placeholder="Enter full address"
                    />
                    {formik.touched.address && formik.errors.address && (
                        <p className="text-red-500 text-xs mt-1">{formik.errors.address as string}</p>
                    )}
                </div>

                <div className="grid grid-cols-2 gap-3">
                    <div>
                        <label className="block text-md font-medium text-gray-900 mb-1">
                            Emergency Contact Name <span className='text-danger'>*</span>
                        </label>
                        <input
                            name="emergency_name"
                            value={formik.values.emergency_name}
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                            className="form-input w-full"
                            placeholder="Emergency contact person"
                        />
                        {formik.touched.emergency_name && formik.errors.emergency_name && (
                            <p className="text-red-500 text-xs mt-1">{formik.errors.emergency_name as string}</p>
                        )}
                    </div>
                    <div>
                        <label className="block text-md font-medium text-gray-900 mb-1">
                            Emergency Phone <span className='text-danger'>*</span>
                        </label>
                        <input
                            name="emergency_phone"
                            value={formik.values.emergency_phone}
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                            className="form-input w-full"
                            placeholder="10 digit mobile number"
                        />
                        {formik.touched.emergency_phone && formik.errors.emergency_phone && (
                            <p className="text-red-500 text-xs mt-1">{formik.errors.emergency_phone as string}</p>
                        )}
                    </div>
                </div>

                <div className="grid grid-cols-2 gap-3">
                    <div>
                        <label className="block text-md font-medium text-gray-900 mb-1">
                            Course <span className='text-danger'>*</span>
                        </label>
                        <Select
                            options={courseOptions}
                            value={courseOptions.find(o => o.value === formik.values.course_id)}
                            onChange={(val: any) => {
                                formik.setFieldValue("course_id", val?.value || "");
                                formik.setFieldValue("batch_id", "");

                                setTimeout(() => {
                                    formik.setFieldTouched("course_id", true);
                                    formik.validateField("course_id");
                                }, 0);
                            }}
                            placeholder="Select course"
                            isLoading={courseOptions.length === 0 && open}
                        />
                        {formik.touched.course_id && formik.errors.course_id && (
                            <p className="text-red-500 text-xs mt-1">{formik.errors.course_id as string}</p>
                        )}
                    </div>
                    <div>
                        <label className="block text-md font-medium text-gray-900 mb-1">
                            Batch / Class <span className='text-danger'>*</span>
                        </label>
                        <Select
                            options={batchOptions}
                            value={batchOptions.find(o => o.value === formik.values.batch_id)}
                             onChange={(val: any) => {
                                formik.setFieldValue("batch_id", val?.value || "");

                                setTimeout(() => {
                                    formik.setFieldTouched("batch_id", true);
                                    formik.validateField("batch_id");
                                }, 0);
                            }}
                            placeholder={formik.values.course_id ? "Select batch" : "Select course first"}
                            isDisabled={!formik.values.course_id}
                            isLoading={batchOptions.length === 0 && formik.values.course_id}
                        />
                        {formik.touched.batch_id && formik.errors.batch_id && (
                            <p className="text-red-500 text-xs mt-1">{formik.errors.batch_id as string}</p>
                        )}
                    </div>
                </div>

                <div className="grid grid-cols-2 gap-3">
                    <div>
                        <label className="block text-md font-medium text-gray-900 mb-1">
                            Total Fees <span className='text-danger'>*</span>
                        </label>
                        <input
                            name="total_fees"
                            type="number"
                            value={formik.values.total_fees}
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                            className="form-input w-full"
                            placeholder="Enter total fees"
                        />
                        {formik.touched.total_fees && formik.errors.total_fees && (
                            <p className="text-red-500 text-xs mt-1">{formik.errors.total_fees as string}</p>
                        )}
                    </div>
                    <div>
                        <label className="block text-md font-medium text-gray-900 mb-1">
                            Initial Payment <span className='text-danger'>*</span>
                        </label>
                        <input
                            name="fees_paid"
                            type="number"
                            value={formik.values.fees_paid}
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                            className="form-input w-full"
                            placeholder="Enter initial payment"
                        />
                        {formik.touched.fees_paid && formik.errors.fees_paid && (
                            <p className="text-red-500 text-xs mt-1">{formik.errors.fees_paid as string}</p>
                        )}
                    </div>
                </div>

                <div className="flex justify-between items-center">
                    <span className="text-sm font-medium text-gray-700">Remaining Balance:</span>
                    <span className={`text-lg font-bold ${remaining > 0 ? 'text-orange-600' : 'text-green-600'}`}>
                        ₹{remaining.toLocaleString()}
                    </span>
                </div>

                <div className="grid grid-cols-2 gap-3">
                    <div>
                        <label className="block text-md font-medium text-gray-900 mb-1">
                            Username <span className='text-danger'>*</span>
                        </label>
                        <div className="relative">
                            <input
                                name="user_name"
                                value={formik.values.user_name}
                                onChange={(e) => {
                                    formik.handleChange(e);
                                    setUsernameAvailable(null);
                                }}
                                onBlur={(e) => {
                                    formik.handleBlur(e);
                                    if (formik.values.user_name) {
                                        checkUsername(formik.values.user_name);
                                    }
                                }}
                                className="form-input w-full pr-20"
                                placeholder="Choose a username"
                            />
                            {usernameChecking && (
                                <div className="absolute right-2 top-2">
                                    <div className="animate-spin rounded-full h-5 w-5 border-b-2 border-primary"></div>
                                </div>
                            )}
                            {usernameAvailable === true && !usernameChecking && (
                                <div className="absolute right-2 top-2 text-green-500">✓</div>
                            )}
                            {usernameAvailable === false && !usernameChecking && (
                                <div className="absolute right-2 top-2 text-red-500">✗</div>
                            )}
                        </div>
                        {formik.touched.user_name && formik.errors.user_name && (
                            <p className="text-red-500 text-xs mt-1">{formik.errors.user_name as string}</p>
                        )}

                        {usernameSuggestions.length > 0 && (
                            <div className="mt-2">
                                <p className="text-xs text-gray-500 mb-1">Suggestions:</p>
                                <div className="flex flex-wrap gap-2">
                                    {usernameSuggestions.map((suggestion, idx) => (
                                        <button
                                            key={idx}
                                            type="button"
                                            onClick={() => applySuggestion(suggestion)}
                                            className="text-xs bg-gray-100 hover:bg-gray-200 px-2 py-1 rounded"
                                        >
                                            {suggestion}
                                        </button>
                                    ))}
                                </div>
                            </div>
                        )}
                    </div>
                    <div>
                        <label className="block text-md font-medium text-gray-900 mb-1">
                            Password <span className='text-danger'>*</span>
                        </label>
                        <div className="relative">
                            <input
                                name="password"
                                type={showPassword ? "text" : "password"}
                                value={formik.values.password}
                                onChange={formik.handleChange}
                                onBlur={formik.handleBlur}
                                className="form-input w-full pr-10"
                                placeholder="Choose a password"
                            />
                            <button
                                type="button"
                                onClick={() => setShowPassword(!showPassword)}
                                className="absolute right-2 top-2 text-gray-500"
                            >
                                {showPassword ? <IconEyeOff className="w-4 h-4" /> : <IconEye className="w-4 h-4" />}
                            </button>
                        </div>
                        {formik.touched.password && formik.errors.password && (
                            <p className="text-red-500 text-xs mt-1">{formik.errors.password as string}</p>
                        )}
                        <p className="text-xs text-gray-400 mt-1">Minimum 6 characters</p>
                    </div>
                </div>

                <div>
                    <label className="block text-md font-medium text-gray-900 mb-1">
                        Notes
                    </label>
                    <textarea
                        name="notes"
                        rows={2}
                        value={formik.values.notes}
                        onChange={formik.handleChange}
                        className="form-textarea w-full"
                        placeholder="Additional notes (optional)"
                    />
                </div>
            </form>
        </Modal>
    );
};

export default ConvertStudent;
