"use client";

import Location from "@core/app/components/Location/Location";
import Saveable from "@core/app/components/Saveable/Saveable";
import ClientsIcon from "@mui/icons-material/AccountBoxOutlined";
import { useEventHandlerStore, EVENT_TYPES } from "@core/Store/EventHandler.Store";
import { useLocationStore } from "@core/Store/Location.Store";
import { useParams } from "next/navigation";
import { useEffect, useState } from "react";
import {
    applyAppointmentDiscount,
    deleteAppointment,
    deleteAppointmentDiscount,
    findAppointmentsAdminByClient,
    sendEmailNotification,
    sendWapNotification,
    updateAppointment,
} from "../Appointments.Service";
import {
    ApplyAppointmentDiscountParams,
    APPOINTMENT_NOTIFICATION_TYPE,
    AppointmentEventByClient,
    DeleteAppointmentDiscountParams,
    UpdateAppointmentParams,
} from "@core/Models/Appointments.model";
import { ChangeServiceParams } from "@models/Appointments.model";
import Textbox from "@core/app/components/Textbox/Textbox";
import { useMenuStore } from "@core/Store/Menu.Store";
import WhatsAppIcon from "@mui/icons-material/WhatsApp";
import EmailOutlinedIcon from "@mui/icons-material/EmailOutlined";
import DeleteIcon from "@mui/icons-material/Delete";

import Switch from "@mui/material/Switch";
import { ThemeProvider } from "@emotion/react";
import turnosXpressTheme from "@core/app/theme/turnosXpress";

import { useSessionStore } from "@core/Store/Sesion.Store";
import { useAlert } from "@core/Store/Alert.Store";
import { ApiError } from "@core/Models/Server.Error.model";
import { useNavigation } from "@core/app/hooks/goto";
import { useConfirmStore } from "@core/Store/Confirm.Store";

import { ButtonGroup } from "@mui/material";
import ButtonMaterial from "@mui/material/Button";
import AppointmentEventHeader from "@core/app/components/AppointmentEventHeader/AppointmentEventHeader";
import PaymentToolbar from "@core/app/components/PaymentToolbar/PaymentToolbar";
import { useBottomToolbarStore } from "@core/Store/BottomToolbar.Store";
import dayjs from "dayjs";

import { TextObjectModalContent } from "@core/Store/TextObjectModal.Store";
import TextObjectFilterItem from "@core/app/components/TextObjectFilterItem/TextObjectFilterItem";
import TextObjectFilter from "@core/app/components/TextObjectFilter/TextObjectFilter";
import filterObjects from "@components/TextObjectFilter/Filter.Service";

import DialogWindow from "@core/app/components/DialogWindow/DialogWindow";
import { DialogActions, DialogContent } from "@mui/material";
import { TextObjectFilterResult } from "@core/Models/TextObjectFilter.model";
import { FindDiscountsParams } from "@core/Models/Discounts.model";
import DiscountsIcon from "@mui/icons-material/LocalOfferOutlined";
import BuildIcon from "@mui/icons-material/Build";
import { changeAppointmentServiceForce } from "../Appointments.Service";
import { FindEmployeesByServiceParams } from "@core/Models/Collaborators.model";
import { FindServicesParams } from "@core/Models/Service.model";

export type UrlData = {
    oid: string;
    clientId: string;
    appointmentId: string;
};

export default function ClientAppointment() {
    const urlData = useParams();
    const oid = urlData.oid;
    const clientId = urlData.clientId;
    const appointmentId = urlData.appointmentId;

    const SessionUser = useSessionStore();
    const location = useLocationStore();
    const eventHandler = useEventHandlerStore();
    const alert = useAlert();
    const confirm = useConfirmStore();
    const menu = useMenuStore();
    const bottomToolbar = useBottomToolbarStore();
    const { goTo } = useNavigation();

    const [notification, setNotification] = useState<boolean>(false);
    const [appointment, setAppointment] = useState<AppointmentEventByClient | undefined>(undefined);

    const [price, setPrice] = useState<string>("");
    const [length, setLength] = useState<string>("");
    const [comments, setComments] = useState<string>("");

    const [dialogDiscountVisible, setDialogDiscountVisible] = useState(false);

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

    const [discountsFilterData, setDiscountsFilterData] = useState<TextObjectFilterResult[]>([]);
    const [discountId, setDiscountId] = useState<string>("");

    const [dialogChangeServiceVisible, setDialogChangeServiceVisible] = useState(false);
    const [servicesFilterData, setServicesFilterData] = useState<TextObjectFilterResult[]>([]);
    const [employeesFilterData, setEmployeesFilterData] = useState<TextObjectFilterResult[]>([]);
    const [newServiceId, setNewServiceId] = useState<string>("");
    const [newEmployeeId, setNewEmployeeId] = useState<string>("");

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

    const [employeesFilterContent] = useState<TextObjectModalContent>({
        header: (
            <div>
                <div style={{ fontWeight: "700", fontSize: "14px", paddingTop: "7px" }}>Seleccionar 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} />,
    });

    useEffect(() => {
        eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
    }, []);

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

        location.add({
            url: "/admin/org/profile/" + oid + "/clients",
            title: "Clientes",
            icon: null,
        });

        location.add({
            url: "/admin/org/" + oid + "/client/" + clientId + "/appointments",
            title: "Turnos reservados",
            icon: <ClientsIcon sx={{ mr: 0.5 }} fontSize="inherit" />,
        });

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

        loadAppointmentData();

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

    useEffect(() => {
        if (!SessionUser.userId) {
            return;
        }

        if (!oid) {
            return;
        }

        const filter: FindDiscountsParams = {
            companyId: oid.toString(),
            sessionUser: SessionUser.userId,
        };
        filterObjects<FindDiscountsParams>("discounts/filter-all", filter).then((res) => {
            setDiscountsFilterData(res);
        }).catch((e) => console.error("Error fetching discounts:", e));

        const filterServices: FindServicesParams = {
            companyId: oid.toString(),
        };
        filterObjects<FindServicesParams>("services/filter-all", filterServices).then((res) => {
            setServicesFilterData(res);
        }).catch((e) => console.error("Error fetching services:", e));
    }, [SessionUser.userId, oid]);

    useEffect(() => {
        if (!newServiceId) {
            setEmployeesFilterData([]);
            return;
        }

        const filterEmployees: FindEmployeesByServiceParams = {
            serviceId: newServiceId,
        };
        filterObjects<FindEmployeesByServiceParams>("employees/employees-by-service", filterEmployees)
            .then((res) => {
                setEmployeesFilterData(res);
            })
            .catch((e) => console.error("Error fetching employees by service:", e));
    }, [newServiceId]);

    useEffect(() => {
        const showAddDiscount = appointment && appointment.discountId !== "" ? false : true;
        const showQuitDiscount = !showAddDiscount;

        if (showAddDiscount) {
            bottomToolbar.set(
                <PaymentToolbar
                    onGotoAppointments={() => {
                        goTo(
                            `/admin/org/profile/${oid}/appointments/${encodeURIComponent(
                                dayjs(appointment?.appointmentDate)
                                    .clone()
                                    .startOf("day")
                                    .toISOString()
                            )}`
                        );
                    }}
                    onApplyDiscount={() => {
                        setDialogDiscountVisible(true);
                    }}
                />
            );
        }

        if (showQuitDiscount) {
            bottomToolbar.set(
                <PaymentToolbar
                    onGotoAppointments={() => {
                        goTo(
                            `/admin/org/profile/${oid}/appointments/${encodeURIComponent(
                                dayjs(appointment?.appointmentDate)
                                    .clone()
                                    .startOf("day")
                                    .toISOString()
                            )}`
                        );
                    }}
                    onQuitDiscount={() => {
                        deleteDiscountHandler();
                    }}
                />
            );
        }

        createMenu();

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

    useEffect(() => {
        if (eventHandler.eventType === EVENT_TYPES.SAVE) {
            if (!appointment || !appointmentId) {
                return;
            }

            const updateDate: UpdateAppointmentParams = {
                id: appointmentId?.toString(),
                start: appointment.appointmentDate,
                length: parseInt(length),
                price: parseFloat(price),
                comments: comments,
                notification: notification,
                sessionUser: SessionUser.userId,
            };
            eventHandler.setEventType(EVENT_TYPES.LOADING);
            updateAppointment(updateDate)
                .then(() => {
                    alert.showSuccess("Turno actualizado");
                })
                .catch((error: ApiError) => {
                    alert.showError(error.format());
                })
                .finally(() => {
                    eventHandler.setEventType(EVENT_TYPES.SLEEP);
                });
        }
    }, [eventHandler.eventType]);

    const createMenu = () => {
        const showAddDiscount = appointment && appointment.discountId !== "" ? false : true;
        const showQuitDiscount = !showAddDiscount;

        menu.clear();

        menu.add({
            text: "Enviar recordatorio por Whatsapp",
            onClick: () => {
                if (!appointmentId) {
                    return;
                }
                eventHandler.setEventType(EVENT_TYPES.LOADING);
                sendWapNotification({
                    appointmentId: appointmentId.toString(),
                    type: APPOINTMENT_NOTIFICATION_TYPE.REMINDER,
                    sessionUser: SessionUser.userId,
                })
                    .then(() => {
                        alert.showSuccess("La notificatión fue enviada con éxito");
                    })
                    .catch((error) => {
                        alert.showError(error.format());
                    })
                    .finally(() => {
                        eventHandler.setEventType(EVENT_TYPES.SLEEP);
                    });
            },
            icon: <WhatsAppIcon />,
        });

        menu.add({
            text: "Enviar recordatorio por Email",
            onClick: () => {
                if (!appointmentId) {
                    return;
                }
                eventHandler.setEventType(EVENT_TYPES.LOADING);
                sendEmailNotification({
                    appointmentId: appointmentId.toString(),
                    type: APPOINTMENT_NOTIFICATION_TYPE.REMINDER,
                    sessionUser: SessionUser.userId,
                })
                    .then(() => {
                        alert.showSuccess("La notificatión fue enviada con éxito");
                    })
                    .catch((error) => {
                        alert.showError(error.format());
                    })
                    .finally(() => {
                        eventHandler.setEventType(EVENT_TYPES.SLEEP);
                    });
            },
            icon: <EmailOutlinedIcon />,
        });

        menu.divider();

        menu.add({
            text: "Enviar alta de turno por Whatsapp",
            onClick: () => {
                if (!appointmentId) {
                    return;
                }
                eventHandler.setEventType(EVENT_TYPES.LOADING);
                sendWapNotification({
                    appointmentId: appointmentId.toString(),
                    type: APPOINTMENT_NOTIFICATION_TYPE.CREATION,
                    sessionUser: SessionUser.userId,
                })
                    .then(() => {
                        alert.showSuccess("La notificatión fue enviada con éxito");
                    })
                    .catch((error) => {
                        alert.showError(error.format());
                    })
                    .finally(() => {
                        eventHandler.setEventType(EVENT_TYPES.SLEEP);
                    });
            },
            icon: <WhatsAppIcon />,
        });

        menu.add({
            text: "Enviar alta de turno por Email",
            onClick: () => {
                if (!appointmentId) {
                    return;
                }
                eventHandler.setEventType(EVENT_TYPES.LOADING);
                sendEmailNotification({
                    appointmentId: appointmentId.toString(),
                    type: APPOINTMENT_NOTIFICATION_TYPE.CREATION,
                    sessionUser: SessionUser.userId,
                })
                    .then(() => {
                        alert.showSuccess("La notificatión fue enviada con éxito");
                    })
                    .catch((error) => {
                        alert.showError(error.format());
                    })
                    .finally(() => {
                        eventHandler.setEventType(EVENT_TYPES.SLEEP);
                    });
            },
            icon: <EmailOutlinedIcon />,
        });

        if (showQuitDiscount) {
            menu.divider();

            menu.add({
                text: "Quitrar Descuento",
                onClick: () => {
                    deleteDiscountHandler();
                },
                icon: <DeleteIcon />,
            });
        }

        if (showAddDiscount) {
            menu.divider();

            menu.add({
                text: "Agregar Descuento",
                onClick: () => {
                    setDialogDiscountVisible(true);
                },
                icon: <DiscountsIcon />,
            });
        }

        menu.divider();

        menu.add({
            text: "Cambiar servicio",
            onClick: () => {
                setNewServiceId("");
                setNewEmployeeId("");
                setDialogChangeServiceVisible(true);
            },
            icon: <BuildIcon />,
        });

        menu.divider();

        menu.add({
            text: "Cancelar turno",
            onClick: () => {
                deleteAppointmentHandler();
            },
            icon: <DeleteIcon />,
        });
    };

    const applyDiscountHandler = () => {
        if (!SessionUser.userId) {
            return;
        }

        if (!oid) {
            return;
        }

        if (!appointmentId) {
            return;
        }

        if (!discountId) {
            return;
        }

        eventHandler.setEventType(EVENT_TYPES.LOADING);

        const data: ApplyAppointmentDiscountParams = {
            discountId: discountId.toString(),
            companyId: oid.toString(),
            appointmentId: appointmentId.toString(),
            sessionUser: SessionUser.userId,
        };

        applyAppointmentDiscount(data)
            .then(() => {
                alert.showSuccess("Descuento aplicado!");
                setDialogDiscountVisible(false);
                loadAppointmentData();
            })
            .catch((error) => {
                alert.showError(error.format());
            })
            .finally(() => {
                eventHandler.setEventType(EVENT_TYPES.NEED_ADD);
            });
    };

    const deleteDiscountHandler = () => {
        if (!SessionUser.userId) {
            console.log("No hay usuario logueado");
            return;
        }

        if (!oid) {
            console.log("No hay organizacion");
            return;
        }

        if (!appointmentId) {
            console.log("No hay turno");
            return;
        }

        eventHandler.setEventType(EVENT_TYPES.LOADING);

        const data: DeleteAppointmentDiscountParams = {
            companyId: oid.toString(),
            appointmentId: appointmentId.toString(),
            sessionUser: SessionUser.userId,
        };

        deleteAppointmentDiscount(data)
            .then(() => {
                alert.showSuccess("Descuento quitado!");
                setDialogDiscountVisible(false);
                loadAppointmentData();
            })
            .catch((error) => {
                alert.showError(error.format());
            })
            .finally(() => {
                eventHandler.setEventType(EVENT_TYPES.NEED_ADD);
            });
    };

    const changeServiceForceHandler = () => {
        if (!SessionUser.userId || !oid || !appointmentId) return;
        if (!newServiceId || !newEmployeeId) {
            alert.showError("Debe seleccionar un servicio y un profesional.");
            return;
        }

        eventHandler.setEventType(EVENT_TYPES.LOADING);

        const data: ChangeServiceParams = {
            id: appointmentId.toString(),
            newServiceId: newServiceId,
            newEmployeeId: newEmployeeId,
            sessionUser: SessionUser.userId,
        };

        changeAppointmentServiceForce(data)
            .then(() => {
                alert.showSuccess("El servicio ha sido cambiado con éxito.");
                setDialogChangeServiceVisible(false);
                loadAppointmentData();
            })
            .catch((error) => {
                alert.showError(error.format ? error.format() : "Ha ocurrido un error al cambiar el servicio");
            })
            .finally(() => {
                eventHandler.setEventType(EVENT_TYPES.SLEEP);
            });
    };

    const loadAppointmentData = () => {
        findAppointmentsAdminByClient({
            _id: appointmentId?.toString(),
        }).then((data) => {
            if (data.events.length > 0) {
                const info = data.events[0];
                setAppointment(info);
                setPrice(info.price.toString());
                setLength(info.length.toString());
                setComments(info.comments);
                createMenu();
            } else {
                setAppointment(undefined);
                setPrice("");
                setLength("");
                setComments("");
            }
        });
    };

    const deleteAppointmentHandler = () => {
        if (!appointmentId) {
            return;
        }

        confirm.show(
            "Estas seguro que queres cancelar el turno?",
            () => {
                eventHandler.setEventType(EVENT_TYPES.LOADING);
                deleteAppointment({
                    id: appointmentId?.toString(),
                    sessionUser: SessionUser.userId,
                })
                    .then(() => {
                        alert.showSuccess("Turno cancelado");
                    })
                    .catch((error: ApiError) => {
                        alert.showError(error.format());
                    })
                    .finally(() => {
                        eventHandler.setEventType(EVENT_TYPES.SLEEP);
                        if (appointment) {
                            goTo(
                                `/admin/org/profile/${oid}/appointments/${encodeURIComponent(
                                    dayjs(appointment.appointmentDate)
                                        .clone()
                                        .startOf("day")
                                        .toISOString()
                                )}`
                            );
                        } else {
                            goTo("/admin/org/" + oid + "/client/" + clientId + "/appointments");
                        }
                    });
            },
            () => {
                eventHandler.setEventType(EVENT_TYPES.SLEEP);
            }
        );
    };

    return (
        <>
            <Saveable>
                <Location bottomSeperation="70px" />

                {appointment && (
                    <div style={{ marginTop: "10px" }}>
                        <div
                            style={{
                                display: "flex",
                                justifyContent: "center",
                                marginTop: "10px",
                                marginBottom: "20px",
                            }}
                        >
                            <ThemeProvider theme={turnosXpressTheme}>
                                <ButtonGroup variant="outlined" aria-label="Basic button group">
                                    <ButtonMaterial variant="contained">Información</ButtonMaterial>
                                    <ButtonMaterial
                                        variant="outlined"
                                        onClick={() => {
                                            goTo(
                                                `/admin/org/${oid}/client/${clientId}/appointments/${appointmentId}/payments`
                                            );
                                        }}
                                    >
                                        Pagos
                                    </ButtonMaterial>
                                </ButtonGroup>
                            </ThemeProvider>
                        </div>

                        <AppointmentEventHeader appointment={appointment} />

                        <Textbox
                            placeholder="Precio unitario"
                            type="number"
                            value={price}
                            width="100%"
                            onChange={(e) => {
                                setPrice(e.target.value);
                                eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
                            }}
                        />
                        {/* <Textbox
                            placeholder="Cantidad"
                            type="number"
                            value={length}
                            width="100%"
                            onChange={(e) => {
                                setLength(e.target.value);
                                eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
                            }}
                        /> */}
                        <Textbox
                            placeholder="Comentarios"
                            type="comments"
                            value={comments}
                            width="100%"
                            onChange={(e) => {
                                setComments(e.target.value);
                                eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
                            }}
                            style={{ height: "200px" }}
                        />

                        <div
                            style={{
                                display: "flex",
                                justifyContent: "center",
                                alignItems: "center",

                                marginTop: "10px",
                            }}
                        >
                            <ThemeProvider theme={turnosXpressTheme}>
                                <Switch
                                    checked={notification}
                                    onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
                                        setNotification(event.target.checked);
                                    }}
                                    size="medium"
                                />
                            </ThemeProvider>
                            <span
                                style={{
                                    fontSize: "16px",
                                    fontWeight: "600",
                                    color: "var(--black)",
                                }}
                            >
                                Enviar notificatión?
                            </span>
                        </div>
                        <DialogWindow
                            visible={dialogDiscountVisible}
                            setVisible={setDialogDiscountVisible}
                        >
                            <>
                                <DialogContent
                                    style={{
                                        maxWidth: "500px",
                                        minWidth: "300px",
                                        margin: "auto",
                                    }}
                                >
                                    <>
                                        <TextObjectFilter
                                            placeholder="Descuento"
                                            content={discountsFilterContent}
                                            data={discountsFilterData}
                                            onChange={(id) => {
                                                setDiscountId(id);
                                            }}
                                        />
                                    </>
                                </DialogContent>
                                <DialogActions>
                                    <ButtonMaterial
                                        variant="contained"
                                        color="primary"
                                        onClick={applyDiscountHandler}
                                    >
                                        Aplicar Descuento
                                    </ButtonMaterial>
                                    <ButtonMaterial
                                        variant="contained"
                                        color="secondary"
                                        onClick={() => {
                                            setDialogDiscountVisible(false);
                                        }}
                                    >
                                        Cancelar
                                    </ButtonMaterial>
                                </DialogActions>
                            </>
                        </DialogWindow>

                        <DialogWindow
                            visible={dialogChangeServiceVisible}
                            setVisible={setDialogChangeServiceVisible}
                        >
                            <>
                                <DialogContent
                                    style={{
                                        maxWidth: "500px",
                                        minWidth: "300px",
                                        margin: "auto",
                                    }}
                                >
                                    <div style={{ padding: "10px 0" }}>
                                        <TextObjectFilter
                                            placeholder="Servicio"
                                            content={servicesFilterContent}
                                            data={servicesFilterData}
                                            onChange={(id) => {
                                                setNewServiceId(id);
                                            }}
                                        />
                                    </div>
                                    <div style={{ padding: "10px 0" }}>
                                        <TextObjectFilter
                                            placeholder="Profesional"
                                            content={employeesFilterContent}
                                            data={employeesFilterData}
                                            onChange={(id) => {
                                                setNewEmployeeId(id);
                                            }}
                                        />
                                    </div>
                                </DialogContent>
                                <DialogActions>
                                    <ButtonMaterial
                                        variant="contained"
                                        color="primary"
                                        onClick={changeServiceForceHandler}
                                    >
                                        Aceptar
                                    </ButtonMaterial>
                                    <ButtonMaterial
                                        variant="contained"
                                        color="secondary"
                                        onClick={() => {
                                            setDialogChangeServiceVisible(false);
                                        }}
                                    >
                                        Cancelar
                                    </ButtonMaterial>
                                </DialogActions>
                            </>
                        </DialogWindow>
                    </div>
                )}
            </Saveable>
        </>
    );
}
