"use client";
import { useParams } from "next/navigation";
import { useState, useEffect } from "react";
import Location from "@components/Location/Location";
import { useLocationStore } from "@store/Location.Store";
import { useEventHandlerStore, EVENT_TYPES } from "@store/EventHandler.Store";
import { useSessionStore } from "@store/Sesion.Store";
import { useAlert } from "@store/Alert.Store";
import StorefrontOutlinedIcon from "@mui/icons-material/StorefrontOutlined";
import OrgConfigIcon from "@mui/icons-material/SettingsOutlined";
import Textbox from "@components/Textbox/Textbox";
import TextPhone from "@components/TextPhone/TextPhone";
import MaterialAlert from "@mui/material/Alert";
import * as Yup from "yup";
import {
    loadOrganizationsById,
    savePublishedStatus,
    updateOrganizationsById,
} from "../Org.Service";
import {
    COMPANY_PUBLISHED_STATUS,
    MyOranizationsView,
    SetOrganizationPublishedStatusParams,
    UpdateCompanyParams,
} from "@models/Company.model";
import { ApiError } from "@models/Server.Error.model";
import { TextObjectModalContent } from "@core/Store/TextObjectModal.Store";
import { TextObjectFilterResult } from "@core/Models/TextObjectFilter.model";
import TextObjectFilterItem from "@core/app/components/TextObjectFilterItem/TextObjectFilterItem";
import categories from "@core/Models/Categories.type";
import TextObjectFilter from "@core/app/components/TextObjectFilter/TextObjectFilter";
import { getSlug } from "@core/app/helpers/Slug";
import { validatePhone } from "@core/helpers/validatePhone";
import { useConfirmStore } from "@core/Store/Confirm.Store";
import Switch from "@core/app/components/Switch/Switch";
import { FindTemplatesParams } from "@core/Models/Templates.model";
import filterObjects from "@core/app/components/TextObjectFilter/Filter.Service";

type UrlData = {
    id: string;
};

export default function OrganizationEdit() {
    const data = useParams<UrlData>();
    const id = data.id;
    const location = useLocationStore();
    const eventHandler = useEventHandlerStore();
    const SessionInfo = useSessionStore();
    const alert = useAlert();
    const confirm = useConfirmStore();
    const [orgName, setOrgName] = useState("");
    const [orgDescription, setOrgDescription] = useState("");
    const [areaCode, setAreaCode] = useState("");
    const [phone, setPhone] = useState("");
    const [heatMapFraction, setHeatMapFraction] = useState("");
    const [appointmentTime, setAppointmentTime] = useState("");
    const [cancellationTime, setCancellationTime] = useState("");
    const [appointmentAlert, setAppointmentAlert] = useState("");
    const [orgSlug, setOrgSlug] = useState("");

    const [orgPublished, setOrgPublished] = useState<COMPANY_PUBLISHED_STATUS | undefined>(
        undefined
    );

    const [savePublishedStatusAvailable, setSavePublishedStatusAvailable] = useState(false);

    const [combosLoaded, setCombosLoaded] = useState<boolean>(false);

    const [categoryFilterContent] = useState<TextObjectModalContent>({
        header: (
            <div>
                <div
                    style={{
                        fontWeight: "700",
                        fontSize: "14px",
                        paddingTop: "7px",
                    }}
                >
                    Seleccionar Categoría:
                </div>
                <p
                    style={{
                        fontWeight: "500",
                        fontSize: "13px",
                        paddingTop: "2px",
                    }}
                >
                    Ingrese el nombre de la categoría para buscarla.
                </p>
            </div>
        ),
        bottom: <div>&nbsp;</div>,
        renderResult: (result: TextObjectFilterResult, index: number) => (
            <TextObjectFilterItem key={index} data={result} />
        ),
    });

    const [categoryFilterData, setCategoryFilterData] = useState<TextObjectFilterResult[]>([]);
    const [categoryId, setCategoryId] = useState<string>("");

    /* WAP NOTIF */

    const [templateWapNotifFilterContent] = useState<TextObjectModalContent>({
        header: (
            <div>
                <div style={{ fontWeight: "700", fontSize: "14px", paddingTop: "7px" }}>
                    Seleccionar Plantilla:
                </div>
                <p style={{ fontWeight: "500", fontSize: "13px", paddingTop: "2px" }}>
                    Ingrese el nombre de la plantilla para buscarla.
                </p>
            </div>
        ),
        bottom: <div>&nbsp;</div>,
        renderResult: (result: TextObjectFilterResult, index: number) => (
            <TextObjectFilterItem key={index} data={result} />
        ),
    });
    const [templateWapNotifFilterData, setTemplateWapNotifFilterData] = useState<
        TextObjectFilterResult[]
    >([]);
    const [templateWapNotifId, setTemplateWapNotifId] = useState<string>("");

    useEffect(() => {
        if (!SessionInfo.userId) return;
        loadTemplatesCombos();
    }, [SessionInfo.userId]);

    /* WAP ALTA */

    const [templateWapAltaFilterContent] = useState<TextObjectModalContent>({
        header: (
            <div>
                <div style={{ fontWeight: "700", fontSize: "14px", paddingTop: "7px" }}>
                    Seleccionar Plantilla:
                </div>
                <p style={{ fontWeight: "500", fontSize: "13px", paddingTop: "2px" }}>
                    Ingrese el nombre de la plantilla para buscarla.
                </p>
            </div>
        ),
        bottom: <div>&nbsp;</div>,
        renderResult: (result: TextObjectFilterResult, index: number) => (
            <TextObjectFilterItem key={index} data={result} />
        ),
    });
    const [templateWapAltaFilterData, setTemplateWapAltaFilterData] = useState<
        TextObjectFilterResult[]
    >([]);
    const [templateWapAltaId, setTemplateWapAltaId] = useState<string>("");

    const loadTemplatesCombos = () => {
        if (!SessionInfo.userId) return;

        const filter: FindTemplatesParams = {
            companyId: id,
            sessionUser: SessionInfo.userId,
        };

        eventHandler.setEventType(EVENT_TYPES.LOADING);

        filterObjects<FindTemplatesParams>("templates/filter-all", filter).then((res) => {
            setTemplateWapNotifFilterData(res);

            const filter: FindTemplatesParams = {
                companyId: id,
                sessionUser: SessionInfo.userId,
            };
            filterObjects<FindTemplatesParams>("templates/filter-all", filter).then((res) => {
                setTemplateWapAltaFilterData(res);
                setCombosLoaded(true);
                eventHandler.setEventType(EVENT_TYPES.SLEEP);
            });
        });
    };

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

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

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

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

        location.add({
            url: "/admin/org/profile/" + id,
            title: "Configuración",
            icon: <OrgConfigIcon sx={{ fontSize: "32px", mr: "10px" }} />,
        });

        loadCategories();
    }, []);

    useEffect(() => {
        if (combosLoaded) {
            eventHandler.setEventType(EVENT_TYPES.LOADING);
            loadOrganizationsById({ id: id, sessionUser: SessionInfo.userId })
                .then((response: MyOranizationsView) => {
                    setOrgName(response.name);
                    setOrgDescription(response.description);
                    setHeatMapFraction(response.heatMapFraction.toString());
                    setAppointmentTime(response.appointmentTime.toString());
                    setCancellationTime(response.cancellationTime.toString());
                    setAppointmentAlert(response.appointmentAlert);
                    setAreaCode(response.phoneAreaCode);
                    setPhone(response.phoneNumber);
                    setCategoryId(response.categoryId.toString());
                    setOrgSlug(getSlug(response.name));
                    setOrgPublished(response.published);

                    requestAnimationFrame(() => {
                        setTemplateWapNotifId(response.templateWapNotifId);
                        setTemplateWapAltaId(response.templateWapAltaId);
                    });
                })
                .catch((error) => {
                    alert.showError(error.format());
                })
                .finally(() => {
                    eventHandler.setEventType(EVENT_TYPES.SLEEP);
                });
        }
    }, [combosLoaded]);

    useEffect(() => {
        if (eventHandler.eventType === EVENT_TYPES.SAVE) {
            eventHandler.setEventType(EVENT_TYPES.LOADING);

            const validationPhoneResult = validatePhone(areaCode, phone);

            if (!validationPhoneResult.isValid) {
                confirm.show(
                    validationPhoneResult.message,
                    () => {},
                    () => {}
                );
                eventHandler.setEventType(EVENT_TYPES.SLEEP);
                return;
            }

            const data: UpdateCompanyParams = {
                id: id,
                name: orgName,
                description: orgDescription,
                categoryId: Number(categoryId),
                sessionUser: SessionInfo.userId,
                heatMapFraction: heatMapFraction === "" ? undefined : parseInt(heatMapFraction),
                appointmentTime: appointmentTime === "" ? undefined : parseInt(appointmentTime),
                cancellationTime: cancellationTime === "" ? undefined : parseInt(cancellationTime),
                appointmentAlert: appointmentAlert,
                phoneAreaCode: areaCode,
                phoneNumber: phone,
                templateWapNotifId: templateWapNotifId === "" ? undefined : templateWapNotifId,
                templateWapAltaId: templateWapAltaId === "" ? undefined : templateWapAltaId,
            };

            const schema = Yup.object().shape({
                id: Yup.string().required("En este momento no es posible procesar su solicitud."),
                name: Yup.string().required("Debe introducir el nombre de la organización."),
                description: Yup.string().required(
                    "Debe introducir la descripción de la organización."
                ),
                categoryId: Yup.number().required(
                    "Debe seleccionar una categoría para la organización."
                ),
                phoneAreaCode: Yup.number()
                    .typeError("Código de área debe ser un número.")
                    .transform((value, originalValue) =>
                        originalValue.toString().trim() === "" ? null : value
                    )
                    .nullable(),
                phoneNumber: Yup.number()
                    .typeError("El teléfono debe ser un número.")
                    .transform((value, originalValue) =>
                        originalValue.toString().trim() === "" ? null : value
                    )
                    .nullable(),
                appointmentAlert: Yup.string().optional().default(""),
                sessionUser: Yup.string().required(
                    "Para crear una organización debe iniciar sesión."
                ),
                heatMapFraction: Yup.number()
                    .typeError("Fracción de tiempo debe ser un número.")
                    .transform((value, originalValue) =>
                        originalValue.toString().trim() === "" ? null : value
                    )
                    .nullable()
                    .integer("Fracción de tiempo debe ser un número entero en minutos.")
                    .positive("Fracción de tiempo debe ser un número."),

                appointmentTime: Yup.number()
                    .typeError("El Plazo Mínimo de Reserva debe ser un número.")
                    .transform((value, originalValue) =>
                        originalValue.toString().trim() === "" ? null : value
                    )
                    .nullable()
                    .integer("El Plazo Mínimo de Reserva debe ser un número entero en horas.")
                    .positive("El Plazo Mínimo de Reserva debe ser un número positivo."),
                cancellationTime: Yup.number()
                    .typeError("El Plazo Mínimo de Cancelación debe ser un número.")
                    .transform((value, originalValue) =>
                        originalValue.toString().trim() === "" ? null : value
                    )
                    .nullable()
                    .integer("El Plazo Mínimo de Cancelación debe ser un número entero en horas.")
                    .positive("El Plazo Mínimo de Cancelación debe ser un número positivo."),
                templateWapNotifId: Yup.string().optional().default(""),
                templateWapAltaId: Yup.string().optional().default(""),
                templateEmailNotifId: Yup.string().optional().default(""),
                templateEmailAltaId: Yup.string().optional().default(""),
            });

            schema
                .validate(data, { abortEarly: true })
                .then(() => {
                    updateOrganizationsById(data)
                        .then(() => {
                            alert.showSuccess("Organizacion actualizada!");
                        })
                        .catch((error: ApiError) => {
                            alert.showError(error.format());
                        })
                        .finally(() => {
                            eventHandler.setEventType(EVENT_TYPES.SLEEP);
                        });
                })
                .catch((error: Yup.ValidationError) => {
                    alert.showError(error.message);
                    eventHandler.setEventType(EVENT_TYPES.SLEEP);
                });
        }
    }, [eventHandler.eventType]);

    const loadCategories = () => {
        setCategoryFilterData(
            categories.map((category) => ({
                id: category.id.toString(),
                name: category.name,
                description: category.description,
            }))
        );
    };

    const getPublishedStatusText = () => {
        if (orgPublished === COMPANY_PUBLISHED_STATUS.PUBLISHED) {
            return "Público";
        } else {
            return "Privado";
        }
    };

    const savePublishedStatusHandler = () => {
        if (!orgPublished) {
            return;
        }

        const data: SetOrganizationPublishedStatusParams = {
            companyId: id,
            published: orgPublished,
            sessionUser: SessionInfo.userId,
        };

        eventHandler.setEventType(EVENT_TYPES.LOADING);
        savePublishedStatus(data)
            .then(() => {
                alert.showSuccess("Estado de publicación actualizado");
            })
            .catch((error) => {
                alert.showError(error.format());
            })
            .finally(() => {
                eventHandler.setEventType(EVENT_TYPES.SLEEP);
            });
    };

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

        if (!id) {
            return;
        }

        if (!savePublishedStatusAvailable) {
            return;
        }
        savePublishedStatusHandler();
    }, [orgPublished]);

    return (
        <>
            <Location />
            <div
                style={{
                    display: "flex",
                    justifyContent: "space-between",
                    alignItems: "center",
                }}
            >
                <p style={{ marginTop: "10px" }}>
                    El perfil de la organización no será visible para los clientes hasta que se
                    publique.
                </p>
                <div
                    style={{
                        marginTop: "10px",
                        display: "flex",
                        flexDirection: "column",
                        alignItems: "center",
                    }}
                >
                    <Switch
                        checked={orgPublished === COMPANY_PUBLISHED_STATUS.PUBLISHED}
                        onChange={(checked) => {
                            setSavePublishedStatusAvailable(true);
                            setOrgPublished(
                                checked
                                    ? COMPANY_PUBLISHED_STATUS.PUBLISHED
                                    : COMPANY_PUBLISHED_STATUS.PRIVATE
                            );
                        }}
                    />
                    <span
                        style={
                            orgPublished === COMPANY_PUBLISHED_STATUS.PUBLISHED
                                ? { color: "var(--green-darkestX2)" }
                                : { color: "var(--error)" }
                        }
                    >
                        {getPublishedStatusText()}
                    </span>
                </div>
            </div>
            <Textbox
                placeholder="Nombre de la organización"
                type="text"
                value={orgName}
                width="100%"
                onChange={(e) => {
                    setOrgName(e.target.value);
                    setOrgSlug(getSlug(e.target.value));
                    eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
                }}
            />
            <a
                style={{
                    fontSize: "14px",
                    paddingLeft: "10px",
                    fontWeight: "600",
                }}
                href={"https://turnosxpress.com.ar/" + orgSlug}
            >
                https://turnosxpress.com.ar/{orgSlug}
            </a>
            <Textbox
                placeholder="Descripción de la organización"
                type="text"
                value={orgDescription}
                width="100%"
                onChange={(e) => {
                    setOrgDescription(e.target.value);
                    eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
                }}
            />

            <TextObjectFilter
                placeholder="Categoría"
                content={categoryFilterContent}
                data={categoryFilterData}
                selectedId={categoryId}
                onChange={(id) => {
                    setCategoryId(id);
                    eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
                }}
            />

            <TextPhone
                label="Teléfono"
                areaCode={areaCode}
                number={phone}
                width="100%"
                onChangeArea={(e) => {
                    setAreaCode(e.target.value);
                    eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
                }}
                onChangePhone={(e) => {
                    setPhone(e.target.value);
                    eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
                }}
            />

            <MaterialAlert severity="info" sx={{ marginTop: "20px" }}>
                <b>Alerta para Turnos:</b> El mensaje que establezca aquí se mostrará al cliente al
                momento de realizar una reserva.
            </MaterialAlert>
            <Textbox
                name="appointmentAlert"
                placeholder="Alerta para turnos"
                type="comments"
                limitSize={255}
                value={appointmentAlert}
                width="100%"
                onChange={(e) => {
                    setAppointmentAlert(e.target.value);
                    eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
                }}
                style={{ minHeight: "120px" }}
            />

            <MaterialAlert severity="info" sx={{ marginTop: "20px" }}>
                <b>Fracción de tiempo:</b> Este parámetro (en minutos) establece la duración de un
                turno. Por ejemplo, si lo configuras en 15, los clientes podrán reservar a las
                08:00, 08:15, 08:30, etc. Si lo configuras en 30, podrán reservar a las 08:00,
                08:30, 09:00, etc. Para turnos de una hora, puedes poner 60.
            </MaterialAlert>
            <Textbox
                name="heatMapFraction"
                placeholder="Fracción de tiempo"
                type="text"
                value={heatMapFraction}
                width="100%"
                onChange={(e) => {
                    setHeatMapFraction(e.target.value);
                    eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
                }}
            />

            <MaterialAlert severity="info" sx={{ marginTop: "20px" }}>
                <b>Plazo mínimo de Reserva:</b> Este parámetro (en horas) indica el plazo de tiempo
                mínimo en el que es posible para el cliente realizar una reserva. Por ejemplo, si lo
                configuras en 2, y un cliente intenta reservar a las 10:00, no podrá hacerlo si son
                las 09:00 o más tarde. Si lo configuras en 24, el cliente deberá reservar con al
                menos 24 horas de anticipación.
            </MaterialAlert>
            <Textbox
                name="appointmentTime"
                placeholder="Plazo Mínimo de Reserva"
                type="text"
                value={appointmentTime}
                width="100%"
                onChange={(e) => {
                    setAppointmentTime(e.target.value);
                    eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
                }}
            />
            <MaterialAlert severity="info" sx={{ marginTop: "20px" }}>
                <b>Plazo mínimo de Cancelación:</b> Este parámetro (en horas) indica el plazo de
                tiempo mínimo en el que es posible para el cliente cancelar una reserva. Por
                ejemplo, si lo configuras en 2, y un cliente intenta cancelar una reserva para las
                10:00, no podrá hacerlo si son las 09:00 o más tarde. Si lo configuras en 24, el
                cliente deberá cancelar con al menos 24 horas de anticipación.
            </MaterialAlert>
            <Textbox
                name="cancellationTime"
                placeholder="Plazo Mínimo de Cancelación"
                type="text"
                value={cancellationTime}
                width="100%"
                onChange={(e) => {
                    setCancellationTime(e.target.value);
                    eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
                }}
            />

            <MaterialAlert severity="info" sx={{ marginTop: "20px" }}>
                <b>Notificaciones:</b> Estos parametros registran las plantillas a utilizar al
                enviar recordatorios por Whatsapp y por Email. Para crear las plantillas debe ir a
                la sección de Plantillas en el panel de control. Si no se configura ninguna
                plantilla se utilizará la plantilla por defecto.
            </MaterialAlert>

            <TextObjectFilter
                placeholder="Recordatorios"
                content={templateWapNotifFilterContent}
                data={templateWapNotifFilterData}
                onChange={(id) => {
                    setTemplateWapNotifId(id);
                    eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
                }}
                selectedId={templateWapNotifId}
            />

            <TextObjectFilter
                placeholder="Alta de Reservas"
                content={templateWapAltaFilterContent}
                data={templateWapAltaFilterData}
                onChange={(id) => {
                    setTemplateWapAltaId(id);
                    eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
                }}
                selectedId={templateWapAltaId}
            />

            <div style={{ marginBottom: "10px" }}>&nbsp;</div>
        </>
    );
}
