import { Form, notification } from "antd";
import { useDispatch, useSelector } from "react-redux";
import { closeModal, setSelectedScheduledAppointment } from "../../../Redux/Slices/appointmentsSlice.js";
import {useEffect, useMemo, useRef, useState} from "react";
import dayjs from "dayjs";
import { useGetAppointmentsQuery } from "../../../Api/appointmentsApi.js";
import { Grid } from "antd";

const { useBreakpoint } = Grid;

const useAppointmentFormModalUI = (createAppointment, patients, cancelAppointment, useGetByPatientIdQuery) => {
    const dispatch = useDispatch();
    const { modalVisible, scheduledData } = useSelector((state) => state.appointmentsUI);
    const [form] = Form.useForm();
    const screens = useBreakpoint();

    const [selectedPatient, setSelectedPatient] = useState(null);
    const [currentStep, setCurrentStep] = useState(0);
    const [appointmentDate, setAppointmentDate] = useState(dayjs(new Date()));
    const [searchPatientString, setSearchPatientString] = useState("");
    const [formValues, setFormValues] = useState({});
    const [results, setResults] = useState("");
    const [isDrawerVisible, setIsDrawerVisible] = useState(false);
    const [searchPreviousAppointments, setSearchPreviousAppointments] = useState("");
    const editor = useRef(null);

    const { data: appointments = [] } = useGetAppointmentsQuery(undefined, {
        pollingInterval: 20000,
    });

    const {
        data: previousAppointments = [],
        isLoading: isLoadingPreviousAppointments,
        isError: isErrorPreviousAppointments,
    } = useGetByPatientIdQuery(selectedPatient?.id, {
        pollingInterval: 20000,
        skip: !selectedPatient,
    });

    const blockStepStyle = { marginBottom: 16 };
    const searchInputStyle = { marginBottom: 16 };
    const chooseContainerStyle = { maxHeight: 400, overflowY: "auto" };
    const loadingContainerStyle = { display: "flex", justifyContent: "center", alignItems: "center", height: 200 };
    const stepsContentStyle = { marginBottom: 16 };
    const stepsIndicatorStyle = { marginBottom: 16 };
    const footerRowStyle = { marginTop: 16 };
    const footerButtonStyle = { marginRight: 8 };

    const screenXS = !screens.sm;
    const direction = screenXS ? "vertical" : "horizontal";

    const filteredPatients = useMemo(
        () =>
            patients.filter((patient) => {
                const searchLower = searchPatientString.toLowerCase();
                return Object.values(patient)
                    .filter((value) => typeof value === "string")
                    .some((value) => value.toLowerCase().includes(searchLower));
            }),
        [patients, searchPatientString]
    );

    const filteredPreviousAppointments = useMemo(
        () =>
            previousAppointments.filter((appointment) => {
                const searchLower = searchPreviousAppointments.toLowerCase();
                return appointment.results?.toLowerCase().includes(searchLower);
            }),
        [previousAppointments, searchPreviousAppointments]
    );

    useEffect(() => {
        if (modalVisible) {
            form.resetFields();
            setSelectedPatient(null);
            setCurrentStep(0);
            setSearchPatientString("");
            setFormValues({});
            setIsDrawerVisible(false);
            setSearchPreviousAppointments("");

            if (scheduledData) {
                const patient = patients.find((p) => p.id === scheduledData.patient_id);
                if (patient) {
                    setSelectedPatient(patient);
                    setCurrentStep(1); // Skip to appointment details step
                    form.setFieldsValue({
                        patient_id: scheduledData.patient_id,
                        type_id: scheduledData.type_id,
                        appointment_datetime: dayjs(scheduledData.appointment_datetime),
                    });
                }
            } else {
                form.setFieldsValue({
                    appointment_datetime: dayjs(new Date()),
                });
            }
        }
    }, [modalVisible, form, scheduledData, patients]);

    const handleResultsChange = (newContent) => {
        setResults(newContent);
    };

    const handleSetSearchPatientString = (e) => {
        setSearchPatientString(e.target.value);
    };

    const handleSetSearchPreviousAppointments = (e) => {
        setSearchPreviousAppointments(e.target.value);
    };

    const getDateString = (date) => {
        return date ? dayjs(date).format("DD.MM.YYYY") : "Не указано";
    };

    const getSelectedPatientBirthdayString = () => {
        return selectedPatient ? getDateString(selectedPatient.birthday) : "Не выбран";
    };

    const resetPatient = () => {
        setSelectedPatient(null);
        form.setFieldsValue({ patient_id: undefined });
    };

    const handleSetAppointmentDate = (date) => setAppointmentDate(date);
    const modalWidth = useMemo(() => (screenXS ? 700 : "90%"), [screenXS]);

    const showDrawer = () => {
        setIsDrawerVisible(true);
    };

    const closeDrawer = () => {
        setIsDrawerVisible(false);
        setSearchPreviousAppointments(""); // Reset search on close
    };

    const handleClickNextButton = async () => {
        if (currentStep === 0) {
            if (!selectedPatient) {
                notification.error({
                    message: "Ошибка",
                    description: "Пожалуйста, выберите пациента.",
                    placement: "topRight",
                });
                return;
            }
            form.setFieldsValue({ patient_id: selectedPatient.id });
            setCurrentStep(1);
        } else if (currentStep === 1) {
            try {
                const values = await form.validateFields();
                setFormValues(values);
                setCurrentStep(2);
            } catch (error) {
                notification.error({
                    message: "Ошибка валидации",
                    description: error.message || "Пожалуйста, заполните все обязательные поля.",
                    placement: "topRight",
                });
            }
        } else if (currentStep === 2) {
            await handleOk();
        }
    };

    const handleClickBackButton = () => {
        if (currentStep > 0) {
            setCurrentStep(currentStep - 1);
        }
    };

    const handleOk = async () => {
        try {
            const values = formValues;

            const appointmentTime = values.appointment_datetime;
            const hasConflict = appointments.some((app) =>
                dayjs(app.appointment_datetime).isSame(appointmentTime, "minute")
            );

            if (hasConflict) {
                notification.error({
                    message: "Конфликт времени",
                    description: "Выбранное время уже занято другим приемом.",
                    placement: "topRight",
                });
                return;
            }

            const data = {
                patient_id: selectedPatient.id,
                type_id: values.type_id,
                appointment_datetime: appointmentTime.format("YYYY-MM-DD HH:mm:ss"),
                days_until_the_next_appointment: values.days_until_the_next_appointment,
                results: results,
            };

            await createAppointment(data).unwrap();

            if (scheduledData) {
                await cancelScheduledAppointment(scheduledData.id);
                dispatch(setSelectedScheduledAppointment(null));
            }

            notification.success({
                message: "Прием создан",
                description: "Прием успешно создан.",
                placement: "topRight",
            });

            dispatch(closeModal());
            form.resetFields();
            setSelectedPatient(null);
            setCurrentStep(0);
            setFormValues({});
        } catch (error) {
            notification.error({
                message: "Ошибка",
                description: error.data?.message || "Не удалось сохранить прием.",
                placement: "topRight",
            });
        }
    };

    const cancelScheduledAppointment = async (selectedScheduledAppointmentId) => {
        try {
            await cancelAppointment(selectedScheduledAppointmentId);
        } catch (error) {
            notification.error({
                message: "Ошибка",
                description: error.data?.message || "Не удалось отменить прием.",
                placement: "topRight",
            });
        }
    };

    const handleCancel = () => {
        form.resetFields();
        setSelectedPatient(null);
        setCurrentStep(0);
        setSearchPatientString("");
        setFormValues({});
        setIsDrawerVisible(false);
        dispatch(closeModal());
    };

    const disableBackButton = currentStep === 0;
    const disableNextButton = currentStep === 0 && !selectedPatient;
    const nextButtonText = currentStep === 2 ? "Создать" : "Далее";

    return {
        form,
        modalVisible,
        selectedPatient,
        setSelectedPatient,
        currentStep,
        searchPatientString,
        appointmentDate,
        results,
        setResults,
        editor,
        handleSetSearchPatientString,
        filteredPatients,
        filteredPreviousAppointments,
        handleSetSearchPreviousAppointments,
        handleOk,
        handleCancel,
        resetPatient,
        getDateString,
        getSelectedPatientBirthdayString,
        handleClickNextButton,
        handleClickBackButton,
        handleSetAppointmentDate,
        handleResultsChange,
        modalWidth,
        disableBackButton,
        disableNextButton,
        nextButtonText,
        blockStepStyle,
        searchInputStyle,
        chooseContainerStyle,
        loadingContainerStyle,
        stepsContentStyle,
        stepsIndicatorStyle,
        footerRowStyle,
        footerButtonStyle,
        screenXS,
        direction,
        isDrawerVisible,
        showDrawer,
        closeDrawer,
        isLoadingPreviousAppointments,
        isErrorPreviousAppointments,
    };
};

export default useAppointmentFormModalUI;