"use client";
import Location from "@core/app/components/Location/Location";
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 { 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 { useNavigation } from "@core/app/hooks/goto";
import { useConfirmStore } from "@core/Store/Confirm.Store";

import { ButtonGroup, DialogActions, DialogContent } from "@mui/material";
import ButtonMaterial from "@mui/material/Button";
import Addable from "@core/app/components/Addable/Addable";
import { getAppointmentEvent } from "../../Appointments.Service";
import { AppointmentEventByClient } from "@core/Models/Appointments.model";
import AppointmentEventHeader from "@core/app/components/AppointmentEventHeader/AppointmentEventHeader";
import { deletePayment, getAppointmentPayments, markAsPayed } from "./AppointmentPayment.Service";
import { IPayment, paymentMethods } from "@core/Models/Payments.model";
import { formatPrice } from "@core/app/helpers/Numbers";
import dayjs from "dayjs";
import { getPaymentIcon } from "@core/app/components/PaymentIcons/PaymentIcons";

import { useBottomToolbarStore } from "@core/Store/BottomToolbar.Store";
import PaymentToolbar from "@core/app/components/PaymentToolbar/PaymentToolbar";
import DialogWindow from "@core/app/components/DialogWindow/DialogWindow";
import { TextObjectFilterResult } from "@core/Models/TextObjectFilter.model";
import TextObjectFilterItem from "@core/app/components/TextObjectFilterItem/TextObjectFilterItem";
import { TextObjectModalContent } from "@core/Store/TextObjectModal.Store";
import TextObjectFilter from "@core/app/components/TextObjectFilter/TextObjectFilter";
import { CLIENT_ACCOUNT_PAYMENT_METHODS } from "@core/Models/ClientAccountMovements.model";
import SecureByPlan, { SECURE_CONTENTS } from "@core/app/components/SecureByPlan/SecureByPlan";

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 { goTo } = useNavigation();
    const bottomToolbar = useBottomToolbarStore();
    const [dialogPayVisible, setDialogPayVisible] = useState<boolean>(false);

    const [appointment, setAppointment] = useState<AppointmentEventByClient | null>(null);

    const [appointmentPayments, setAppointmentPayments] = useState<IPayment[]>([]);

    const [remainingBalance, setRemainingBalance] = useState<number>(0);

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

    const [paymentMethhodFilterData, setPaymentMethodFilterData] = useState<
        TextObjectFilterResult[]
    >([]);
    const [paymentMethodId, setPaymentMethodId] = useState<CLIENT_ACCOUNT_PAYMENT_METHODS>(
        CLIENT_ACCOUNT_PAYMENT_METHODS.CASH
    );

    useEffect(() => {
        loadPaymentMethods();
    }, []);

    const loadPaymentMethods = () => {
        setPaymentMethodFilterData(
            paymentMethods.map((category) => ({
                id: category.id.toString(),
                name: category.name,
                description: category.description,
            }))
        );
    };

    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" }} />,
        });

        loadAppointmentEvent();
    }, []);

    useEffect(() => {
        calculateRemainingBalance();
    }, [appointmentPayments]);

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

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

    const calculateRemainingBalance = () => {
        const total = appointment?.price ?? 0;
        const paid = appointmentPayments.reduce((acc, payment) => acc + payment.amount, 0);

        setRemainingBalance(total - paid);
    };

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

        if (!appointmentId) {
            return;
        }

        eventHandler.setEventType(EVENT_TYPES.LOADING);

        getAppointmentEvent({
            appointmentId: appointmentId.toString(),
            sessionUser: SessionUser.userId,
        })
            .then((data) => {
                setAppointment(data);
            })
            .catch((error) => {
                alert.showError(error.format());
            })
            .finally(() => {
                eventHandler.setEventType(EVENT_TYPES.NEED_ADD);
                loadAppointmentPayments();
            });
    };

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

        if (!appointmentId) {
            return;
        }

        eventHandler.setEventType(EVENT_TYPES.LOADING);

        getAppointmentPayments({
            appointmentId: appointmentId.toString(),
            sessionUser: SessionUser.userId,
        })
            .then((data) => {
                setAppointmentPayments(data);
            })
            .catch((error) => {
                alert.showError(error.format());
            })
            .finally(() => {
                eventHandler.setEventType(EVENT_TYPES.NEED_ADD);
            });
    };

    const deletePaymentHandler = (paymentId: string) => {
        if (!SessionUser.userId) {
            return;
        }

        if (!paymentId) {
            return;
        }

        eventHandler.setEventType(EVENT_TYPES.LOADING);

        deletePayment({
            id: paymentId,
            sessionUser: SessionUser.userId,
        })
            .then(() => {
                loadAppointmentEvent();
            })
            .catch((error) => {
                alert.showError(error.format());
            })
            .finally(() => {
                eventHandler.setEventType(EVENT_TYPES.NEED_ADD);
            });
    };

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

        if (!appointmentId) {
            return;
        }

        if (appointment?.payment) {
            alert.showSuccess("El turno ya está pagado");
            return;
        }

        eventHandler.setEventType(EVENT_TYPES.LOADING);

        markAsPayed({
            appointmentId: appointmentId.toString(),
            method: paymentMethodId,
            sessionUser: SessionUser.userId,
        })
            .then(() => {
                loadAppointmentEvent();
            })
            .catch((error) => {
                alert.showError(error.format());
            })
            .finally(() => {
                setDialogPayVisible(false);
                eventHandler.setEventType(EVENT_TYPES.NEED_ADD);
            });
    };

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

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

            <SecureByPlan content={SECURE_CONTENTS.PAYMENTS} companyId={`${oid}`}>
                <>
                    <Addable
                        onClick={() => {
                            goTo(
                                `/admin/org/${oid}/client/${clientId}/appointments/${appointmentId}/payments/create`
                            );
                        }}
                    >
                        {appointment && (
                            <div style={{ marginTop: "20px" }}>
                                <AppointmentEventHeader appointment={appointment} showPaymentInfo />
                            </div>
                        )}

                        {appointmentPayments && (
                            <div style={{ marginTop: "20px" }}>
                                {appointmentPayments.map((payment, index) => (
                                    <div
                                        key={"payment-" + index}
                                        onClick={() => {
                                            confirm.show(
                                                `¿Estás seguro de querer eliminar este pago de ${formatPrice(
                                                    payment.amount
                                                )}?`,
                                                () => {
                                                    deletePaymentHandler(payment._id);
                                                },
                                                () => { }
                                            );
                                        }}
                                    >
                                        <div
                                            style={{
                                                display: "flex",
                                                flexDirection: "row",
                                                justifyContent: "space-between",
                                                backgroundColor: "var(--white-dark)",
                                                padding: "15px",
                                                borderRadius: "10px",
                                                marginBottom: "10px",
                                                cursor: "pointer",
                                            }}
                                        >
                                            <div
                                                style={{
                                                    display: "flex",
                                                    flexDirection: "row",
                                                    alignItems: "center",
                                                    gap: "10px",
                                                }}
                                            >
                                                <div>{getPaymentIcon(payment.method)}</div>
                                                <div>
                                                    <div
                                                        style={{
                                                            fontSize: "14px",
                                                            fontWeight: "bold",
                                                        }}
                                                    >
                                                        {payment.description}
                                                    </div>
                                                    <div
                                                        style={{
                                                            fontSize: "12px",
                                                            color: "var(--gray-dark)",
                                                        }}
                                                    >
                                                        {dayjs(payment.createdAt).format(
                                                            "DD MMMM YYYY HH:mm"
                                                        )}
                                                    </div>
                                                </div>
                                            </div>
                                            <div
                                                style={{
                                                    fontSize: "14px",
                                                    fontWeight: "bold",
                                                }}
                                            >
                                                {formatPrice(payment.amount)}
                                            </div>
                                        </div>
                                    </div>
                                ))}
                            </div>
                        )}

                        <div>
                            <div
                                style={{
                                    display: "flex",
                                    flexDirection: "row",
                                    justifyContent: "space-between",
                                    padding: "15px",
                                    borderRadius: "10px",
                                    marginBottom: "10px",
                                    color: "var(--error)",
                                }}
                            >
                                <div>
                                    <div
                                        style={{
                                            fontSize: "14px",
                                            fontWeight: "bold",
                                        }}
                                    >
                                        Saldo restante
                                    </div>
                                </div>
                                <div
                                    style={{
                                        fontSize: "14px",
                                        fontWeight: "bold",
                                    }}
                                >
                                    {formatPrice(remainingBalance)}
                                </div>
                            </div>
                        </div>
                        <DialogWindow visible={dialogPayVisible} setVisible={setDialogPayVisible}>
                            <>
                                <DialogContent
                                    style={{
                                        maxWidth: "500px",
                                        minWidth: "300px",
                                        margin: "auto",
                                    }}
                                >
                                    <>
                                        <TextObjectFilter
                                            placeholder="Método de pago"
                                            content={paymentMethodFilterContent}
                                            data={paymentMethhodFilterData}
                                            onChange={(id) => {
                                                setPaymentMethodId(
                                                    id as CLIENT_ACCOUNT_PAYMENT_METHODS
                                                );
                                            }}
                                        />
                                    </>
                                </DialogContent>
                                <DialogActions>
                                    <ButtonMaterial
                                        variant="contained"
                                        color="primary"
                                        onClick={markAsPayedHandler}
                                    >
                                        Pagar
                                    </ButtonMaterial>
                                    <ButtonMaterial
                                        variant="contained"
                                        color="secondary"
                                        onClick={() => {
                                            setDialogPayVisible(false);
                                        }}
                                    >
                                        Cancelar
                                    </ButtonMaterial>
                                </DialogActions>
                            </>
                        </DialogWindow>
                    </Addable>
                </>
            </SecureByPlan>
        </>
    );
}
