import BorderSeparatorApp from "@components/BorderSeparatorApp";
import { formatDateString } from "@helpers/FormatString";
import { useForm } from "@hooks/useForm";
import {
    clearAvailabilityByDays,
    clearSuspendedDataByAcademicRecord,
    setOpenForm,
    startCreateSportsReservations,
    startGetSuspensionUntilByAcademicRecord,
    startShowAvailabilityByDays,
} from "@redux/slices/operators/SportsReservations";
import dayjs from "dayjs";
import React, { useEffect, useMemo, useState } from "react";
import { Button, Col, Form, Modal, Row } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import { Link } from "react-router-dom";
import Swal from "sweetalert2";
import {
    AvatarApp,
    CheckBoxApp,
    InputApp,
    ModalApp,
    SelectSearchApp,
} from "../../../components";
import AddStudentsApp from "../../../components/AddStudentApp";
import { IconApp } from "../../../components/IconApp";
import { OptionsSportsAreas } from "../../../components/Options/sports/OptionsSportsAreas";
import { OptionsSportsHours } from "../../../components/Options/sports/OptionsSportsHours";

const defaultValues = {
    area: "",
    day: "",
    hour: "",
    accepted_terms: false,
    companions_count: 0,
    companions: [],
    errors: {},
};

export default function AddReservationModal({
    academicRecordProp = null,
    areaProp,
    callback = () => {},
}) {
    const dispatch = useDispatch();

    const { openForm, suspendedDataByAcademicRecord, availabilityByDays } =
        useSelector((state) => state.sportsReservations);

    const [academicRecord, setAcademicRecord] = useState(null);

    const { values, handleInputChange, setInputValue, setErrors, reset } =
        useForm(defaultValues);
    const {
        area,
        day,
        hour,
        accepted_terms,
        companions_count,
        companions,
        errors,
    } = values;

    const today = new Date().toISOString().split("T")[0];
    const currentTime = new Date().toTimeString().split(" ")[0].slice(0, 5);

    const blockedDaysFromAvailability =
        availabilityByDays?.blocked_days_by_student ?? [];
    const reservedHoursByDay = availabilityByDays?.reserved_hours_by_day ?? {};

    const reservedHours = new Set(reservedHoursByDay?.[day] ?? []);

    const academicRecordId =
        academicRecord?.id ?? academicRecordProp?.id ?? null;
    const reservedDaysByStudent = new Set(blockedDaysFromAvailability);

    const hourOptions = [
        ...OptionsSportsHours.filter((option) => {
            if (day !== today) {
                return true;
            }

            if (option.value > currentTime) {
                return true;
            }

            return reservedHours.has(option.value);
        }).map((option) =>
            reservedHours.has(option.value)
                ? {
                      ...option,
                      label: `${option.label} (Reservado)`,
                      isDisabled: true,
                  }
                : option,
        ),
    ];

    const allowedDates = useMemo(() => {
        const todayDate = dayjs();
        const maxDate = dayjs().add(48, "hour");

        return Array.from({ length: 3 }, (_, index) =>
            todayDate.add(index, "day"),
        ).filter((date) => {
            const isSunday = date.day() === 0;
            if (isSunday) {
                return false;
            }

            return date.valueOf() <= maxDate.valueOf();
        });
    }, []);

    const daysKey = useMemo(() => {
        return allowedDates.map((date) => date.format("YYYY-MM-DD")).join(",");
    }, [allowedDates]);

    const dateOptions = [
        ...allowedDates.map((date) => {
            const value = date.format("YYYY-MM-DD");
            const isReserved = reservedDaysByStudent.has(value);

            return {
                value,
                label: isReserved
                    ? `${formatDateString(
                          value,
                          false,
                          false,
                          false,
                          true,
                      )} (Ya reservaste una vez en este día)`
                    : formatDateString(value, false, false, false, true),
                isDisabled: isReserved,
            };
        }),
    ];

    const disableHour = useMemo(() => {
        return !area || !day;
    }, [area, day]);

    //* Si se recibe la data del estudiante por props, usarla en lugar de seleccion manual
    useEffect(() => {
        if (academicRecordProp) {
            setAcademicRecord(academicRecordProp);
        }
    }, [academicRecordProp]);

    //* Obtener disponibilidad de selectores de fechas (reservadas por el alumno) y de horas (todos los registros hechos por todos los alumnos)
    useEffect(() => {
        if (!academicRecordId || allowedDates.length === 0 || !area) {
            return;
        }

        dispatch(
            startShowAvailabilityByDays({
                academic_record_id: academicRecordId,
                days: daysKey,
                area,
            }),
        );
    }, [academicRecordId, allowedDates.length, area, daysKey]);

    //* Conocer si el estudiante tiene suspensión de derecho a reserva
    useEffect(() => {
        if (academicRecord) {
            dispatch(
                startGetSuspensionUntilByAcademicRecord(academicRecord?.id),
            );
        }
    }, [academicRecord]);

    useEffect(() => {
        if (areaProp) {
            setInputValue("area", areaProp);
        }
    }, [areaProp]);

    useEffect(() => {
        setInputValue("day", "");
        setInputValue("hour", "");
    }, [area]);

    useEffect(() => {
        setInputValue("hour", "");
    }, [day]);

    const handleDeleteAcademicRecord = () => {
        if (!academicRecordProp) {
            setAcademicRecord(null);
            setInputValue("day", "");
            setInputValue("hour", "");
            dispatch(clearAvailabilityByDays());
            dispatch(clearSuspendedDataByAcademicRecord());
        }
    };

    const handleClose = () => {
        dispatch(setOpenForm(null));
        reset();
        handleDeleteAcademicRecord();
        // dispatch(clearActive());
    };

    const handleCompanionsCountChange = (e) => {
        const count = parseInt(e.target.value, 10) || 0;
        const normalizedCount = Math.max(0, count);

        setInputValue("companions_count", normalizedCount);

        const current = Array.isArray(companions) ? companions : [];
        const next = current.slice(0, normalizedCount);

        while (next.length < normalizedCount) {
            next.push("");
        }

        setInputValue("companions", next);
    };

    const handleCompanionNameChange = (index, value) => {
        const current = Array.isArray(companions) ? companions : [];
        const next = [...current];
        next[index] = value;
        setInputValue("companions", next);
    };

    const handleSave = (e) => {
        e.preventDefault();

        if (!academicRecord) {
            Swal.fire({
                icon: "warning",
                title: "Sin estudiante seleccionado",
                text: "Seleccione al menos un estudiante para continuar",
                width: 440,
            });
            return;
        }

        if (!accepted_terms) {
            Swal.fire({
                icon: "warning",
                title: "Términos y condiciones no aceptados",
                text: "Debe aceptar los términos y condiciones para poder registrar una reserva deportiva",
                width: 660,
            });
            return;
        }

        Swal.fire({
            icon: "question",
            title: "Confirmar acción",
            text: "¿Desea registrar esta reserva deportiva?",
            showConfirmButton: true,
            confirmButtonText: "Sí, registrar",
            confirmButtonColor: "#134586",
            showCancelButton: true,
            cancelButtonText: "Cancelar",
            customClass: {
                confirmButton: "confirm-button-class",
            },
            didOpen: () => {
                const confirmButton = document.querySelector(
                    ".confirm-button-class",
                );

                if (confirmButton) {
                    confirmButton.style.marginRight = "20px";
                }
            },
            allowEnterKey: false,
            allowOutsideClick: false,
            allowEscapeKey: false,
            width: 350,
        }).then((result) => {
            if (result.isConfirmed) {
                dispatch(
                    startCreateSportsReservations(
                        {
                            ...values,
                            student_number: academicRecord?.student_number,
                        },
                        setErrors,
                        async () => {
                            // Pasarle el day de este formulario para que la petición de la lista la haga con el día que se acaba de registrar
                            await callback(day);
                            await handleClose();
                        },
                    ),
                );
            }
        });
    };

    return (
        <ModalApp
            titleModal="Registrar reserva deportiva"
            openModal={openForm}
            onCloseModal={handleClose}
            size="lg"
            Action={() => null}
        >
            <Form onSubmit={handleSave}>
                <Modal.Body>
                    {!academicRecordProp && (
                        <Row className="mb-4">
                            <Col md={12}>
                                {!academicRecord ? (
                                    <AddStudentsApp
                                        multipleCheck={false}
                                        exceptStudents={[]}
                                        estatusStudent={["NORMAL"]}
                                        textInButton={"Seleccionar estudiante"}
                                        classNameButton="btn btn-block"
                                        getAsObject={true}
                                        withLeads={false}
                                        callback={(students) => {
                                            const student =
                                                students?.[0] || null;

                                            if (student) {
                                                setAcademicRecord(student);
                                            }
                                        }}
                                    />
                                ) : (
                                    <div className="d-flex justify-content-center">
                                        <AvatarApp
                                            img={academicRecord?.student.uri}
                                            textToGenerateAvatar={
                                                academicRecord?.full_name
                                            }
                                            size={35}
                                        />

                                        <div className="d-flex flex-column text-size-12">
                                            <strong
                                                data-academic_record_id={
                                                    academicRecord.id
                                                }
                                            >
                                                {academicRecord?.student_number ? (
                                                    <Link
                                                        to={`/app/students/form/${academicRecord.student_number}`}
                                                        target="_blank"
                                                        rel="noreferrer"
                                                        style={{
                                                            color: "rgb(60, 75, 100)",
                                                        }}
                                                    >
                                                        <span>
                                                            {academicRecord?.student_number ||
                                                                ""}

                                                            {" - "}

                                                            {academicRecord?.full_name ||
                                                                ""}
                                                        </span>
                                                    </Link>
                                                ) : (
                                                    <span className="ms-2">
                                                        {academicRecord?.full_name ||
                                                            "-"}
                                                    </span>
                                                )}
                                            </strong>

                                            <span className="text-size-10">
                                                {academicRecord?.curriculum
                                                    ?.rvoe_name || "-"}
                                            </span>
                                        </div>

                                        <div className="mt-2 ms-3">
                                            <IconApp
                                                iconClassName="fa-solid fa-trash fa-xl mx-2"
                                                description={
                                                    "Quitar estudiante"
                                                }
                                                color={"red"}
                                                fontSize={"18px"}
                                                isClickable
                                                onClick={
                                                    handleDeleteAcademicRecord
                                                }
                                            />
                                        </div>
                                    </div>
                                )}
                            </Col>
                        </Row>
                    )}

                    {!!academicRecord && (
                        <>
                            {suspendedDataByAcademicRecord?.is_suspended ? (
                                <div
                                    className="w-100 text-center py-2"
                                    style={{
                                        backgroundColor: "#fff4f4",
                                        border: "1px solid #f2bcbc",
                                        borderRadius: "10px",
                                        color: "#8a1f1f",
                                    }}
                                >
                                    <div className="text-size-13 fw-bold mb-2">
                                        Estudiante con suspensión de derecho a
                                        reserva
                                    </div>
                                    <div className="text-size-12">
                                        No es posible registrar una reserva
                                        deportiva para este estudiante en este
                                        momento.
                                    </div>
                                    <div className="text-size-12 mt-2">
                                        Suspensión vigente hasta:{" "}
                                        <strong>
                                            {formatDateString(
                                                suspendedDataByAcademicRecord?.suspended_until,
                                                true,
                                                false,
                                                false,
                                                true,
                                            )}
                                        </strong>
                                    </div>
                                </div>
                            ) : (
                                <>
                                    <BorderSeparatorApp
                                        title={"Detalles de la reserva"}
                                        marginTop={"mt-0"}
                                        marginTopLine={"mt-1"}
                                        showColon={false}
                                        fontSize={"15px"}
                                        color="rgb(35, 96, 146)"
                                    />
                                    <Row>
                                        <Col md={12}>
                                            <SelectSearchApp
                                                title="Área"
                                                placeholder={
                                                    "Seleccione el área que desea reservar"
                                                }
                                                name="area"
                                                value={area}
                                                onChange={
                                                    academicRecordProp
                                                        ? handleInputChange
                                                        : () => {}
                                                }
                                                options={OptionsSportsAreas}
                                                required
                                                disabled={!academicRecordProp}
                                                errorText={
                                                    errors.area &&
                                                    errors.area[0]
                                                }
                                            />
                                        </Col>

                                        <Col xs={12} md={6}>
                                            <SelectSearchApp
                                                title="Fecha"
                                                placeholder={
                                                    "Seleccione una fecha"
                                                }
                                                name="day"
                                                value={day}
                                                onChange={handleInputChange}
                                                options={dateOptions}
                                                required
                                                infoText={
                                                    !area ? (
                                                        <span className="text-black text-size-11">
                                                            Seleccione un área
                                                            para habilitar.
                                                        </span>
                                                    ) : (
                                                        ""
                                                    )
                                                }
                                                disabled={!area}
                                                errorText={
                                                    errors.day && errors.day[0]
                                                }
                                            />
                                        </Col>

                                        <Col xs={12} md={6}>
                                            <SelectSearchApp
                                                title="Hora"
                                                placeholder={
                                                    "Seleccione una hora"
                                                }
                                                name="hour"
                                                value={hour}
                                                options={hourOptions}
                                                required
                                                disabled={disableHour}
                                                onChange={
                                                    disableHour
                                                        ? () => {}
                                                        : handleInputChange
                                                }
                                                infoText={
                                                    disableHour ? (
                                                        <span className="text-black text-size-11">
                                                            Seleccione un área y
                                                            una fecha para
                                                            habilitar.
                                                        </span>
                                                    ) : (
                                                        ""
                                                    )
                                                }
                                                errorText={
                                                    errors.hour &&
                                                    errors.hour[0]
                                                }
                                            />
                                        </Col>
                                    </Row>

                                    {/* Acompañantes */}
                                    <div className="mt-4">
                                        <BorderSeparatorApp
                                            title={"Acompañantes"}
                                            marginTopLine={"mt-1"}
                                            showColon={false}
                                            fontSize={"15px"}
                                            color="rgb(35, 96, 146)"
                                        />
                                        <Row>
                                            <Col
                                                xs={12}
                                                sm={12}
                                                md={12}
                                                lg={6}
                                                xl={6}
                                                xxl={6}
                                            >
                                                <SelectSearchApp
                                                    title="¿Cuántas personas adicionales asistirán?"
                                                    name="companions_count"
                                                    value={companions_count}
                                                    onChange={
                                                        handleCompanionsCountChange
                                                    }
                                                    options={[
                                                        {
                                                            value: 0,
                                                            label: "Solo yo",
                                                        },
                                                        ...Array.from(
                                                            { length: 3 },
                                                            (_, index) =>
                                                                index + 1,
                                                        ).map((value) => ({
                                                            value,
                                                            label: String(
                                                                value,
                                                            ),
                                                        })),
                                                    ]}
                                                />
                                            </Col>
                                        </Row>

                                        <Row>
                                            {companions_count > 0 && (
                                                <Col xs={12} className="mt-2">
                                                    <Row>
                                                        {companions.map(
                                                            (name, index) => (
                                                                <Col
                                                                    key={`companion-${index}`}
                                                                    xs={12}
                                                                    md={6}
                                                                >
                                                                    <div>
                                                                        <InputApp
                                                                            type="text"
                                                                            title={`Acompañante ${index + 1}`}
                                                                            value={
                                                                                name
                                                                            }
                                                                            placeholder="Nombre completo"
                                                                            onChange={(
                                                                                e,
                                                                            ) =>
                                                                                handleCompanionNameChange(
                                                                                    index,
                                                                                    e
                                                                                        .target
                                                                                        .value,
                                                                                )
                                                                            }
                                                                        />
                                                                    </div>
                                                                </Col>
                                                            ),
                                                        )}
                                                    </Row>
                                                </Col>
                                            )}
                                        </Row>
                                    </div>

                                    <BorderSeparatorApp
                                        title={"Términos y condiciones"}
                                        marginTop={"mt-5"}
                                        marginTopLine={"mt-1"}
                                        showColon={false}
                                        fontSize={"15px"}
                                        color="rgb(35, 96, 146)"
                                    />
                                    <Row className="d-flex justify-content-center mt-4">
                                        {!!area && (
                                            <Col md={12}>
                                                <div className="sports-reservations-terms">
                                                    <div className="terms-box p-3">
                                                        <div className="terms-header d-flex align-items-center mb-2">
                                                            <i className="bi bi-file-earmark-text me-2"></i>
                                                            <span className="fw-semibold">
                                                                Proceso de
                                                                reserva y acceso
                                                            </span>
                                                        </div>

                                                        <div className="terms-content mb-3">
                                                            {OptionsSportsAreas.find(
                                                                (option) =>
                                                                    option.value ===
                                                                    area,
                                                            )?.mainTerms || (
                                                                <span>
                                                                    No se han
                                                                    establecido
                                                                    términos y
                                                                    condiciones
                                                                    para el área
                                                                    seleccionada.
                                                                </span>
                                                            )}
                                                        </div>

                                                        <div className="document-box minimal-style regulation-footer d-flex justify-content-between align-items-center">
                                                            <div>
                                                                <div className="fw-semibold text-size-13">
                                                                    Reglamento
                                                                    completo
                                                                </div>
                                                                <div className="text-size-12 text-muted">
                                                                    Consulta el
                                                                    siguiente
                                                                    documento
                                                                    para conocer
                                                                    todos los
                                                                    términos y
                                                                    condiciones.
                                                                </div>
                                                            </div>

                                                            <a
                                                                href="/documents/reservas-deportivas/reglamento-de-padel.pdf"
                                                                target="_blank"
                                                                rel="noopener noreferrer"
                                                                className="btn btn-sm btn-outline-primary"
                                                            >
                                                                Ver documento
                                                            </a>
                                                        </div>
                                                    </div>
                                                </div>
                                            </Col>
                                        )}

                                        <Col
                                            md={"auto"}
                                            className="mt-4 text-center"
                                        >
                                            <CheckBoxApp
                                                label="Acepto los términos y condiciones de uso"
                                                className={
                                                    "custom-checkbox-app no-align"
                                                }
                                                style={{ fontSize: "14px" }}
                                                type="checkbox"
                                                name="accepted_terms"
                                                checked={accepted_terms}
                                                onChange={handleInputChange}
                                            />
                                        </Col>
                                    </Row>
                                </>
                            )}
                        </>
                    )}
                </Modal.Body>

                <Modal.Footer>
                    <div className="d-flex justify-content-between w-100">
                        <Button variant="secondary" onClick={handleClose}>
                            Cerrar
                        </Button>

                        {academicRecord &&
                            !suspendedDataByAcademicRecord?.is_suspended && (
                                <Button type="submit">
                                    Registrar reserva
                                    <IconApp iconClassName="fa fa-save ms-2" />
                                </Button>
                            )}
                    </div>
                </Modal.Footer>
            </Form>
        </ModalApp>
    );
}
