"use client";
import TextObjectFilter from "@components/TextObjectFilter/TextObjectFilter";
import TextObjectFilterItem from "@components/TextObjectFilterItem/TextObjectFilterItem";
import { FindEmployeesByServiceParams } from "@models/Collaborators.model";
import { TextObjectFilterResult } from "@models/TextObjectFilter.model";
import { EVENT_TYPES, useEventHandlerStore } from "@store/EventHandler.Store";
import { TextObjectModalContent } from "@store/TextObjectModal.Store";
import { useEffect, useState } from "react";
import filterObjects from "@components/TextObjectFilter/Filter.Service";
import AppointmentsCalendar from "../Calendar/Calendar";
import style from "./Appointment.module.css";
import Button from "@core/app/components/Button/Button";
import dayjs from "dayjs";
import {
    CreateAppointmentParams,
    FindAppointmentSchedulesParams,
    GetAvailableDatesResult,
} from "@core/Models/Appointments.model";
import { useSessionStore } from "@core/Store/Sesion.Store";
import Link from "next/link";
import { LOGIN_ACTIONS, useLoginActionStore } from "@core/Store/LoginAction.Store";
import { createAppointment, getAvailableDates } from "./Appointment.Service";
import { useAlert } from "@core/Store/Alert.Store";
import { useNavigation } from "@core/app/hooks/goto";
import MaterialAlert from "@mui/material/Alert";

export interface AppointmentProps {
    companyId: string;
    serviceId: string;
    appointmentAlert?: string;
}

export default function Appointment(props: AppointmentProps) {
    const { serviceId, companyId, appointmentAlert = "" } = props;
    const eventHandler = useEventHandlerStore();
    const SessionInfo = useSessionStore();
    const loginAction = useLoginActionStore();
    const alert = useAlert();
    const { goTo } = useNavigation();

    const [selectedDate, setSelectedDate] = useState<dayjs.Dayjs>(dayjs());
    const [availableDates, setAvailableDates] = useState<GetAvailableDatesResult>({
        availableDates: [],
        inRangeDates: [],
    });

    useEffect(() => {
        loginAction.setLoginAction(LOGIN_ACTIONS.APPOINTMENT_CREATE);
        loginAction.setUrl("/landing/service/" + serviceId);
    }, []);

    const [employeeFilterContent] = useState<TextObjectModalContent>({
        header: (
            <div>
                <div style={{ fontWeight: "700", fontSize: "14px", paddingTop: "7px" }}>
                    Seleccionar un profesional:
                </div>
                <p style={{ fontWeight: "500", fontSize: "13px", paddingTop: "2px" }}>
                    Ingrese el nombre del profesional para buscarlo.
                </p>
            </div>
        ),
        bottom: <div>&nbsp;</div>,
        renderResult: (result: TextObjectFilterResult, index: number) => (
            <TextObjectFilterItem key={index} data={result} />
        ),
    });

    const [employeeFilterData, setEmployeeFilterData] = useState<TextObjectFilterResult[]>([]);
    const [employeeId, setEmployeeId] = useState<string>("");

    useEffect(() => {
        eventHandler.setEventType(EVENT_TYPES.SLEEP);
        const filter: FindEmployeesByServiceParams = {
            serviceId,
        };
        filterObjects<FindEmployeesByServiceParams>("employees/employees-by-service", filter).then(
            (res) => {
                setEmployeeFilterData(res);
            }
        );
    }, [serviceId]);

    //---------------------------------

    const [scheduleFilterContent] = useState<TextObjectModalContent>({
        header: (
            <div>
                <div style={{ fontWeight: "700", fontSize: "14px", paddingTop: "7px" }}>
                    Seleccionar un horario:
                </div>
                <p style={{ fontWeight: "500", fontSize: "13px", paddingTop: "2px" }}>
                    Ingrese el horario para buscarlo.
                </p>
            </div>
        ),
        bottom: <div>&nbsp;</div>,
        renderResult: (result: TextObjectFilterResult, index: number) => (
            <TextObjectFilterItem key={index} data={result} />
        ),
    });

    const [scheduleFilterData, setScheduleFilterData] = useState<TextObjectFilterResult[]>([]);
    const [scheduleId, setScheduleId] = useState<string>("");

    useEffect(() => {
        const filter: FindAppointmentSchedulesParams = {
            companyId: companyId,
            serviceId: serviceId,
            employeeId: employeeId,
            dateDay: selectedDate.toISOString(),
        };

        if (!employeeId) {
            return;
        }
        eventHandler.setEventType(EVENT_TYPES.LOADING);
        filterObjects<FindAppointmentSchedulesParams>("appointments/get-schedules", filter).then(
            (res) => {
                //eventHandler.setEventType(EVENT_TYPES.SLEEP);
                setScheduleFilterData(res);

                getAvailableDates({
                    companyId: companyId,
                    serviceId: serviceId,
                    employeeId: employeeId,
                    length: 60,
                    sessionUser: SessionInfo.userId,
                })
                    .then((result) => {
                        setAvailableDates(result);
                    })
                    .catch((error) => {
                        setAvailableDates({ availableDates: [], inRangeDates: [] });
                        alert.showError(error.format());
                    })
                    .finally(() => {
                        eventHandler.setEventType(EVENT_TYPES.SLEEP);
                    });
            }
        );
    }, [serviceId, employeeId, selectedDate]);

    const onReservarClick = () => {
        const data: CreateAppointmentParams = {
            companyId: companyId,
            serviceId: serviceId,
            employeeId: employeeId,
            userId: SessionInfo.userId,
            start: scheduleId,
            sessionUser: SessionInfo.userId,
            validation: true,
        };

        eventHandler.setEventType(EVENT_TYPES.LOADING);

        createAppointment(data)
            .then(() => {
                alert.showSuccess("Turno reservado con éxito");
                setTimeout(() => {
                    goTo("/");
                }, 1000);
            })
            .catch((error) => {
                alert.showError(error.format());
            })
            .finally(() => {
                eventHandler.setEventType(EVENT_TYPES.SLEEP);
            });
    };

    return (
        <div>
            <h1 className={style.appointmentTitle}>Reservar turno</h1>
            <p className={style.appointmentResume}>
                <b>Bienvenido/a.</b> Para realizar una reserva, primero seleccione un profesional de
                la lista y luego elija una fecha y un horario disponibles. En caso de no haber
                turnos disponibles, el sistema se lo informará. No dude en contactarnos ante
                cualquier duda o inconveniente.
            </p>
            {!SessionInfo.loged && (
                <>
                    <div
                        style={{
                            color: "var(--black)",
                            fontSize: "16px",
                            fontWeight: "600",
                            marginTop: "20px",
                            marginBottom: "20px",
                            paddingLeft: "30px",
                            paddingRight: "30px",
                        }}
                    >
                        Para poder reservar un turno tenes que estar registrado en turnosxpress y
                        haber iniciado sesión. Si ya tienes una cuenta puedes{" "}
                        <Link href="/landing/login">Iniciar sesión aquí</Link> o en caso de no estar
                        registrado puedes <Link href="/landing/signup">Registrarte aquí</Link>.
                    </div>
                </>
            )}
            {SessionInfo.loged && (
                <div style={{ marginLeft: "30px", marginRight: "30px", textAlign: "left" }}>
                    <TextObjectFilter
                        placeholder="Seleccionar Profesional:"
                        content={employeeFilterContent}
                        data={employeeFilterData}
                        onChange={(id) => {
                            setEmployeeId(id);
                            setScheduleFilterData([]);
                            setScheduleId("");
                        }}
                    />
                    {employeeId != "" && (<AppointmentsCalendar
                        availableDates={availableDates}
                        onChange={(selDate) => {
                            setSelectedDate(selDate);
                            setScheduleFilterData([]);
                            setScheduleId("");
                        }}
                    />)}

                    {employeeId && scheduleFilterData.length > 0 && (
                        <TextObjectFilter
                            placeholder="Seleccionar Horario:"
                            content={scheduleFilterContent}
                            data={scheduleFilterData}
                            onChange={(id) => {
                                setScheduleId(id);
                            }}
                        />
                    )}

                    {employeeId && scheduleFilterData.length == 0 && (
                        <div
                            style={{
                                color: "var(--white)",
                                backgroundColor: "var(--error)",
                                borderRadius: "10px",
                                fontSize: "16px",
                                fontWeight: "600",
                                marginTop: "20px",
                                padding: "15px",
                            }}
                        >
                            <p>
                                No hay horarios dispobibles para el día seleccionado. Intente
                                seleccionar otro día u otro profesional para este servicio.
                            </p>
                            <p style={{ marginTop: "10px" }}>
                                En caso de no aparecer horarios disponibles, es probable que la
                                organización aun no haya habilitado las reservas en el periodo que
                                se encuentra seleccionado.
                            </p>
                            <p style={{ marginTop: "10px" }}>
                                Ante cualquier inconveniente por favor comuniquese con nosotros.
                            </p>
                        </div>
                    )}

                    {appointmentAlert && (
                        <MaterialAlert severity="info" sx={{ marginTop: "20px" }}>
                            <div dangerouslySetInnerHTML={{ __html: appointmentAlert }}></div>
                        </MaterialAlert>
                    )}

                    <Button
                        text="Reservar"
                        color="primary"
                        width="100%"
                        onClick={() => {
                            onReservarClick();
                        }}
                        style={{ marginTop: "20px", marginBottom: "20px" }}
                    />
                </div>
            )}
        </div>
    );
}
