"use client";
import style from "./page.module.css";
import { useState, useEffect, useRef } from "react";
import { useParams } from "next/navigation";
import Location from "@components/Location/Location";
import { useLocationStore } from "@store/Location.Store";
import ClientsIcon from "@mui/icons-material/AccountBoxOutlined";
import { useEventHandlerStore, EVENT_TYPES } from "@store/EventHandler.Store";
import StorefrontOutlinedIcon from "@mui/icons-material/StorefrontOutlined";
import HomeIcon from "@mui/icons-material/Home";
import IconButton from "@mui/material/IconButton";
import ArrowLeftIcon from "@mui/icons-material/ArrowLeft";
import ArrowRightIcon from "@mui/icons-material/ArrowRight";
import FastRewindIcon from "@mui/icons-material/FastRewind";
import FastForwardIcon from "@mui/icons-material/FastForward";
import Addable from "@components/Addable/Addable";
import { useNavigation } from "@hooks/goto";
import { DaySchedule, ScheduleView } from "react-schedule-view";
import { scViewTurnosExpress, TXCalendarEvent } from "@themes/scheduleView";
import { useBottomToolbarStore } from "@store/BottomToolbar.Store";
import {
    addDisabledRepeatDate,
    createAppointment,
    findAppointmentsAdminByDate,
} from "./Appointment.Service";
import { CreateAppointmentParams, FindAppointmentsParams } from "@core/Models/Appointments.model";
import { useAlert } from "@core/Store/Alert.Store";
import MaterialAlert from "@mui/material/Alert";

import filterObjects from "@components/TextObjectFilter/Filter.Service";

import dayjs, { ManipulateType } from "dayjs";
import "dayjs/locale/es";
import Filterable from "@core/app/components/Filterable/Filterable";
import { useFilterStore } from "@core/Store/Filter.Store";
import { TextObjectFilterResult } from "@core/Models/TextObjectFilter.model";
import { FindEmployeesParams } from "@core/Models/Collaborators.model";
import { TextObjectModalContent } from "@core/Store/TextObjectModal.Store";
import TextObjectFilterItem from "@core/app/components/TextObjectFilterItem/TextObjectFilterItem";
import TextObjectFilter from "@core/app/components/TextObjectFilter/TextObjectFilter";
import { useAppointmentsViewStore } from "@core/Store/AppointmentsView.Store";
import ActionDialog from "@core/app/components/ActionDialog/ActionDialog";
import { Button } from "@mui/material";
import { useSessionStore } from "@core/Store/Sesion.Store";
import { AddRepeatDisabledDateParams } from "@core/Models/Repeats.model";
import CalendarRowView from "@core/app/components/CalendarRowView/CalendarRowView";
import useWindowSize from "@core/app/hooks/WindowSize";

import ContentPasteIcon from "@mui/icons-material/ContentPaste";
import CloseIcon from "@mui/icons-material/Close";
import { useClipboardStore } from "@store/Clipboard.Store";
import { useTimePickerStore } from "@store/TimePicker.Store";
import ApiRequest from "@services/Api.Service";

dayjs.locale("es");

type UrlData = {
    id: string;
    appdate: string;
};

enum CalendarViewMode {
    ROW = "row",
    COLUMN = "column",
}

interface FilterContentProps {
    data: TextObjectFilterResult[];
    setCollaboratorId: (id: string) => void;
}

const FilterContent = (props: FilterContentProps) => {
    //const filter = useFilterStore();
    const appoinmentsView = useAppointmentsViewStore();
    //const onChangeHandler = (field: string, value: string) => {};

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

    return (
        <>
            {!appoinmentsView.collaboratorId && (
                <TextObjectFilter
                    placeholder="Colaborador"
                    content={collaboratorFilterContent}
                    data={props.data}
                    onChange={(id) => {
                        props.setCollaboratorId(id);
                    }}
                />
            )}
        </>
    );
};

export interface AppointmentToolbarProps {
    onNext: (mode: ManipulateType) => void;
    onPrevious: (mode: ManipulateType) => void;
    onHome: () => void;
}

const AppointmentsToolbar = (props: AppointmentToolbarProps) => {
    return (
        <div
            style={{
                display: "flex",
                justifyContent: "center",
                alignItems: "center",
                width: "100%",
                height: "60px",
                color: "var(--white)",
            }}
        >
            <IconButton
                color="inherit"
                onClick={() => {
                    props.onPrevious("week");
                }}
            >
                <FastRewindIcon sx={{ ml: 1, mr: 1 }} />
            </IconButton>
            <IconButton
                color="inherit"
                onClick={() => {
                    props.onPrevious("day");
                }}
            >
                <ArrowLeftIcon sx={{ ml: 1, mr: 1 }} />
            </IconButton>
            <IconButton
                color="inherit"
                onClick={() => {
                    props.onHome();
                }}
            >
                <HomeIcon sx={{ ml: 1, mr: 1 }} />
            </IconButton>

            <IconButton
                color="inherit"
                onClick={() => {
                    props.onNext("day");
                }}
            >
                <ArrowRightIcon sx={{ ml: 1, mr: 1 }} />
            </IconButton>
            <IconButton
                color="inherit"
                onClick={() => {
                    props.onNext("week");
                }}
            >
                <FastForwardIcon sx={{ ml: 1, mr: 1 }} />
            </IconButton>
        </div>
    );
};

export default function OrganizationProfile() {
    const data = useParams<UrlData>();
    const id = data.id;
    const appointmentDate = data.appdate
        ? dayjs(decodeURIComponent(data.appdate))
        : dayjs(new Date());
    const location = useLocationStore();
    const eventHandler = useEventHandlerStore();
    const filter = useFilterStore();
    const alert = useAlert();
    const SessionInfo = useSessionStore();
    const appointmentsView = useAppointmentsViewStore();
    const { goTo } = useNavigation();

    const [windowWidth] = useWindowSize();

    const bottomToolbar = useBottomToolbarStore();

    const [viewMode, setViewMode] = useState<CalendarViewMode>(CalendarViewMode.ROW);

    const [currentDate, setCurrentDate] = useState<dayjs.Dayjs>(appointmentDate);

    const [calendarEventsCount, setCalendarEventsCount] = useState<number>(0);
    const [calendarFrom, setCalendarFrom] = useState<number>(8);
    const [calendarTo, setCalendarTo] = useState<number>(23);
    const [calendarData, setCalendarData] = useState<DaySchedule<TXCalendarEvent>[]>([
        {
            name: "",
            events: [],
        },
    ]);

    const [collaboratorFilterData, setCollaboratorFilterData] = useState<TextObjectFilterResult[]>(
        []
    );
    const [collaboratorId, setCollaboratorId] = useState<string>("");

    const [dialogVisible, setDialogVisible] = useState<boolean>(false);
    const [dialogCalendarEvent, setDialogCalendarEvent] = useState<TXCalendarEvent | undefined>(
        undefined
    );


    const timePicker = useTimePickerStore();
    const copiedAppointment = useClipboardStore(state => state.copiedAppointment);
    const setCopiedAppointment = useClipboardStore(state => state.setCopiedAppointment);
    
    useEffect(() => {
        if (copiedAppointment) {
            eventHandler.setEventType(EVENT_TYPES.SLEEP);
        } else {
            eventHandler.setEventType(copiedAppointment ? EVENT_TYPES.SLEEP : EVENT_TYPES.NEED_ADD);
        }
    }, [copiedAppointment]);
        


    useEffect(() => {
        eventHandler.setEventType(copiedAppointment ? EVENT_TYPES.SLEEP : EVENT_TYPES.NEED_ADD);
        bottomToolbar.set(
            <AppointmentsToolbar onNext={next} onPrevious={previous} onHome={homeHandler} />
        );

        filter.setTitle("Filtrar Turnos");
        filter.clearFilterData();
        filter.setContent(
            <FilterContent data={collaboratorFilterData} setCollaboratorId={setCollaboratorId} />
        );
        filter.setOnFilter(() => {});
    }, [collaboratorFilterData]);

    useEffect(() => {
        const filter: FindEmployeesParams = {
            companyId: id,
        };
        filterObjects<FindEmployeesParams>("employees/filter-all", filter).then((res) => {
            setCollaboratorFilterData(res);
        });

        setDialogCalendarEvent(undefined);
    }, []);

    /*     useEffect(() => {
        eventHandler.setEventType(EVENT_TYPES.LOADING);
        console.log("currentDate:", currentDate);
    }, [currentDate]); */

    useEffect(() => {
        if (windowWidth < 600) {
            setViewMode(CalendarViewMode.ROW);
        } else {
            setViewMode(CalendarViewMode.COLUMN);
        }
    }, [windowWidth]);

    useEffect(() => {
        location.clear();

        location.add({
            url: "/admin/org",
            title: "Mis organizaciones",
            icon: null,
        });

        location.add({
            url: "/admin/org/profile/" + id,
            title: "Organizacion",
            icon: <StorefrontOutlinedIcon sx={{ mr: 0.5 }} fontSize="inherit" />,
        });

        location.add({
            url: "",
            title: "Turnos",
            icon: <ClientsIcon sx={{ fontSize: "32px", mr: "10px" }} />,
        });
    }, []);

    useEffect(() => {
        loadCalendarData();
        setDialogCalendarEvent(undefined);
    }, [currentDate, collaboratorId]);

    useEffect(() => {
        return () => {
            bottomToolbar.clear();
        };
    }, []);

    const loadCalendarData = () => {
        const dataFind: FindAppointmentsParams = {
            companyId: id,
            dateDay: dayjs(currentDate).clone().startOf("day").toISOString(),
            employeeId: appointmentsView.collaboratorId
                ? appointmentsView.collaboratorId
                : collaboratorId,
        };

        const filteredFilter = Object.fromEntries(
            Object.entries(dataFind).filter(([, v]) => v && v.toString().trim() !== "")
        );

        eventHandler.setEventType(EVENT_TYPES.LOADING);

        findAppointmentsAdminByDate(filteredFilter)
            .then((data) => {
                setCalendarEventsCount(data.events.length);
                setCalendarFrom(data.from);
                setCalendarTo(data.to);
                setCalendarData([
                    {
                        name: "",
                        events: data.events,
                    },
                ]);
            })
            .catch((error) => {
                alert.showError(error.format());
            })
            .finally(() => {
                eventHandler.setEventType(copiedAppointment ? EVENT_TYPES.SLEEP : EVENT_TYPES.NEED_ADD);
            });
    };

    const next = (mode: ManipulateType = "day") => {
        setCurrentDate((prevDate) => prevDate.clone().add(1, mode));
    };

    const previous = (mode: ManipulateType = "day") => {
        setCurrentDate((prevDate) => prevDate.clone().subtract(1, mode));
    };

    const homeHandler = () => {
        setCurrentDate(dayjs(new Date()).startOf("day"));
    };

    const handleAdd = () => {
        eventHandler.setEventType(EVENT_TYPES.LOADING);
        goTo(
            "/admin/org/profile/" +
                id +
                "/appointments/" +
                encodeURIComponent(dayjs(currentDate).clone().startOf("day").toISOString()) +
                "/create/"
        );
    };

    const crearTurnoConRepeticion = () => {
        if (!dialogCalendarEvent) {
            return;
        }

        const serviceId = dialogCalendarEvent.serviceId;
        const employeeId = dialogCalendarEvent.employeeId;
        const repeatId = dialogCalendarEvent.repeatId;
        const startHour = Math.floor(dialogCalendarEvent.startTime);
        const startMinutes = (dialogCalendarEvent.startTime - startHour) * 60;
        const startDate = dayjs(currentDate.clone().startOf("day"))
            .hour(startHour)
            .minute(startMinutes);

        if (!serviceId || !employeeId) {
            return;
        }

        const data: CreateAppointmentParams = {
            companyId: id,
            serviceId: serviceId,
            employeeId: employeeId,
            clientId: dialogCalendarEvent.clientId,
            repeatId: repeatId,
            start: startDate.toISOString(),
            notification: false,
            validation: false,
            sessionUser: SessionInfo.userId,
        };

        eventHandler.setEventType(EVENT_TYPES.LOADING);
        createAppointment(data)
            .then(() => {
                setDialogVisible(false);
                loadCalendarData();
                alert.showSuccess("Turno creado con éxito");
            })
            .catch((error) => {
                alert.showError(error.format());
            })
            .finally(() => {
                eventHandler.setEventType(EVENT_TYPES.SLEEP);
            });
    };


    const handleMoveAppointment = async (newDay: dayjs.Dayjs) => {

        if (!copiedAppointment || !copiedAppointment.appointmentId) return;
        timePicker.hide();
        eventHandler.setEventType(EVENT_TYPES.LOADING);

        const newStart = dayjs(currentDate).hour(newDay.hour()).minute(newDay.minute()).second(0).millisecond(0).toISOString();
        const oldStart = dayjs(copiedAppointment.startTime);
        const oldEnd = dayjs(copiedAppointment.endTime);
        const durationMin = oldEnd.diff(oldStart, 'minute');
        const newEnd = dayjs(newStart).add(durationMin, 'minute').toISOString();

        try {
            await ApiRequest.post("/appointments/move-appointment-force", {
                id: copiedAppointment.appointmentId,
                companyId: id,
                newStart: newStart,
                newEnd: newEnd,
                sessionUser: SessionInfo.userId,
            });
            alert.showSuccess("Turno movido con éxito");
            setCopiedAppointment(null);
            loadCalendarData();
        } catch (error: unknown) {
            console.error(error);
            alert.showError("Error al mover el turno");
        } finally {
            eventHandler.setEventType(copiedAppointment ? EVENT_TYPES.SLEEP : EVENT_TYPES.NEED_ADD);
        }
    };

    const anularTurnoConRepeticion = () => {
        if (!dialogCalendarEvent) {
            return;
        }

        if (!dialogCalendarEvent.repeatId) {
            return;
        }

        if (!SessionInfo.userId) {
            return;
        }

        const data: AddRepeatDisabledDateParams = {
            repeatId: dialogCalendarEvent.repeatId,
            disableDate: dayjs(
                currentDate.clone().startOf("day").hour(dialogCalendarEvent.startTime)
            ).toDate(),
            sessionUser: SessionInfo.userId,
        };

        eventHandler.setEventType(EVENT_TYPES.LOADING);

        addDisabledRepeatDate(data)
            .then(() => {
                setDialogVisible(false);
                loadCalendarData();
                alert.showSuccess("Reserva anulada con éxito");
            })
            .catch((error) => {
                alert.showError(error.format());
            })
            .finally(() => {
                eventHandler.setEventType(EVENT_TYPES.SLEEP);
            });
    };

    return (
        <>
            <Addable onClick={handleAdd}>
                <Filterable />
                <Location />
                <div className={style.appointmentsTitle}>
                    <h4>{dayjs(currentDate).format("dddd DD [de] MMMM, YYYY")}</h4>
                </div>

                <div className={style.appointmentsContent}>
                    {calendarEventsCount === 0 && (
                        <div>
                            <MaterialAlert>
                                <b>No hay turnos cargados para la fecha seleccionada.</b> Para
                                cargar un nuevo turno haga click en el boton ➕ inferior.
                            </MaterialAlert>
                        </div>
                    )}
                    {calendarEventsCount > 0 && viewMode === CalendarViewMode.ROW && (
                        <CalendarRowView
                            daySchedules={calendarData}
                            onEventLongPress={(event) => {
                                setCopiedAppointment(event); alert.showSuccess("ID del turno copiado exitosamente.");
                            }}
                            handleEventClick={(event) => {
                                if (!event.appointmentId) {
                                    setDialogCalendarEvent(event);
                                    setDialogVisible(true);
                                    return;
                                }
                                setCopiedAppointment(null);
                                goTo(
                                    "/admin/org/" +
                                        id +
                                        "/client/" +
                                        event.clientId +
                                        "/appointments/" +
                                        event.appointmentId
                                );
                            }}
                        />
                    )}
                    {calendarEventsCount > 0 && viewMode === CalendarViewMode.COLUMN && (
                        <div 
                        >
                            <ScheduleView
                            daySchedules={calendarData}
                            viewStartTime={calendarFrom}
                            viewEndTime={calendarTo}
                            theme={scViewTurnosExpress(60)}
                            handleEventClick={(event) => {
                                if (!event.appointmentId) {
                                    setDialogCalendarEvent(event);
                                    setDialogVisible(true);
                                    return;
                                }
                                
                                setCopiedAppointment(null);
                                goTo(
                                    "/admin/org/" +
                                        id +
                                        "/client/" +
                                        event.clientId +
                                        "/appointments/" +
                                        event.appointmentId
                                );
                            }}
                        />
                        </div>
                    )}
                </div>
                <ActionDialog
                    title="Crear turno"
                    message="Este turno aún no ha sido creado ya que pertenece a una reserva con repetición automática."
                    visible={dialogVisible}
                    setVisible={setDialogVisible}
                    buttons={[
                        <Button
                            key="cancelButton"
                            variant="contained"
                            color="secondary"
                            onClick={() => {
                                setDialogVisible(false);
                            }}
                        >
                            Cancelar
                        </Button>,
                        <Button
                            key="disableButton"
                            variant="contained"
                            color="warning"
                            onClick={() => {
                                anularTurnoConRepeticion();
                            }}
                        >
                            Anular
                        </Button>,
                        <Button
                            key="createButton"
                            variant="contained"
                            color="success"
                            onClick={() => {
                                crearTurnoConRepeticion();
                            }}
                        >
                            Crear
                        </Button>,
                    ]}
                />
                {copiedAppointment && (
                    <>
                        <div 
                            className={style.buttonCancelPaste}
                            onClick={() => {
                                setCopiedAppointment(null);
                            }}
                        >
                            <CloseIcon />
                        </div>
                        <div 
                            className={style.buttonPaste}
                            onClick={() => timePicker.show((newDay) => handleMoveAppointment(newDay))}
                        >
                            <ContentPasteIcon />
                        </div>
                    </>
                )}


            </Addable>
        </>
    );
}
