import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
import { Head, Link } from '@inertiajs/react';
import axios from 'axios';
import { useMemo, useState } from 'react';
import Swal from 'sweetalert2';

export default function Index({
    sesion,
    estados = [],
}) {
    /*
    |--------------------------------------------------------------------------
    | DATOS BASE
    |--------------------------------------------------------------------------
    */

    const edicion = sesion?.edicion ?? null;

    const programa =
        edicion?.programa ?? null;

    const inscripciones =
        edicion?.inscripciones ?? [];

    const asistenciasRegistradas =
        sesion?.asistencias ?? [];

    /*
    |--------------------------------------------------------------------------
    | MAPA DE ASISTENCIAS EXISTENTES
    |--------------------------------------------------------------------------
    */

    const mapaAsistencias = useMemo(() => {
        const mapa = {};

        asistenciasRegistradas.forEach(
            (asistencia) => {
                mapa[
                    asistencia.inscripcion_id
                ] = asistencia;
            }
        );

        return mapa;
    }, [asistenciasRegistradas]);

    /*
    |--------------------------------------------------------------------------
    | ESTADO LOCAL
    |--------------------------------------------------------------------------
    */

    const [guardando, setGuardando] =
        useState(false);

    const [asistencias, setAsistencias] =
        useState(() =>
            inscripciones.map(
                (inscripcion) => {
                    const existente =
                        mapaAsistencias[
                            inscripcion.id
                        ];

                    return {
                        inscripcion_id:
                            inscripcion.id,

                        estado:
                            existente?.estado ??
                            'PRESENTE',

                        hora_registro:
                            existente
                                ?.hora_registro
                                ? String(
                                      existente.hora_registro
                                  ).substring(
                                      0,
                                      5
                                  )
                                : '',

                        observaciones:
                            existente
                                ?.observaciones ??
                            '',
                    };
                }
            )
        );

    /*
    |--------------------------------------------------------------------------
    | HELPERS
    |--------------------------------------------------------------------------
    */

    const obtenerEstudiante = (
        inscripcion
    ) => {
        return (
            inscripcion?.estudiante ??
            null
        );
    };

    const nombreEstudiante = (
        estudiante
    ) => {
        if (!estudiante) {
            return 'Estudiante no disponible';
        }

        return [
            estudiante.apellidos,
            estudiante.nombres,
        ]
            .filter(Boolean)
            .join(' ');
    };

    const formatearFecha = (
        fecha
    ) => {
        if (!fecha) {
            return '—';
        }

        const valor = String(
            fecha
        ).substring(0, 10);

        const [anio, mes, dia] =
            valor.split('-');

        if (
            !anio ||
            !mes ||
            !dia
        ) {
            return fecha;
        }

        return `${dia}/${mes}/${anio}`;
    };

    const formatearHora = (
        hora
    ) => {
        if (!hora) {
            return '—';
        }

        return String(
            hora
        ).substring(0, 5);
    };

    /*
    |--------------------------------------------------------------------------
    | MODIFICAR ASISTENCIA
    |--------------------------------------------------------------------------
    */

    const actualizarAsistencia = (
        inscripcionId,
        campo,
        valor
    ) => {
        setAsistencias(
            (prev) =>
                prev.map(
                    (item) =>
                        item.inscripcion_id ===
                        inscripcionId
                            ? {
                                  ...item,
                                  [campo]:
                                      valor,
                              }
                            : item
                )
        );
    };

    /*
    |--------------------------------------------------------------------------
    | MARCAR TODOS
    |--------------------------------------------------------------------------
    */

    const marcarTodos = (
        estado
    ) => {
        setAsistencias(
            (prev) =>
                prev.map(
                    (item) => ({
                        ...item,
                        estado,
                    })
                )
        );
    };

    /*
    |--------------------------------------------------------------------------
    | GUARDAR
    |--------------------------------------------------------------------------
    */

    const guardarAsistencias =
        async () => {
            if (
                guardando ||
                !asistencias.length
            ) {
                return;
            }

            const confirmacion =
                await Swal.fire({
                    icon: 'question',
                    title:
                        '¿Guardar asistencia?',
                    text:
                        'Se registrará la asistencia de todos los participantes mostrados.',
                    showCancelButton:
                        true,
                    confirmButtonText:
                        'Sí, guardar',
                    cancelButtonText:
                        'Cancelar',
                    reverseButtons: true,
                });

            if (
                !confirmacion.isConfirmed
            ) {
                return;
            }

            setGuardando(true);

            try {
                const response =
                    await axios.post(
                        route(
                            'formacion.asistencias.guardar',
                            {
                                formacionSesion:
                                    sesion.id,
                            }
                        ),
                        {
                            asistencias:
                                asistencias.map(
                                    (
                                        item
                                    ) => ({
                                        inscripcion_id:
                                            item.inscripcion_id,

                                        estado:
                                            item.estado,

                                        hora_registro:
                                            item.hora_registro ||
                                            null,

                                        observaciones:
                                            item.observaciones ||
                                            null,
                                    })
                                ),
                        },
                        {
                            headers: {
                                Accept:
                                    'application/json',

                                'X-Requested-With':
                                    'XMLHttpRequest',
                            },
                        }
                    );

                await Swal.fire({
                    icon: 'success',
                    title:
                        'Asistencia guardada',
                    text:
                        response.data
                            ?.message ??
                        'Asistencias registradas correctamente.',
                });
            } catch (error) {
                await Swal.fire({
                    icon: 'error',
                    title:
                        'No se pudo guardar',

                    text:
                        error.response
                            ?.data
                            ?.message ??
                        Object.values(
                            error
                                .response
                                ?.data
                                ?.errors ??
                                {}
                        )?.[0]?.[0] ??
                        'Ocurrió un error al registrar la asistencia.',
                });
            } finally {
                setGuardando(false);
            }
        };

    /*
    |--------------------------------------------------------------------------
    | RESUMEN
    |--------------------------------------------------------------------------
    */

    const resumen = useMemo(
        () => {
            const resultado = {
                PRESENTE: 0,
                FALTA: 0,
                TARDANZA: 0,
                JUSTIFICADO: 0,
            };

            asistencias.forEach(
                (item) => {
                    if (
                        Object.prototype.hasOwnProperty.call(
                            resultado,
                            item.estado
                        )
                    ) {
                        resultado[
                            item.estado
                        ]++;
                    }
                }
            );

            return resultado;
        },
        [asistencias]
    );

    /*
    |--------------------------------------------------------------------------
    | ESTILOS
    |--------------------------------------------------------------------------
    */

    const inputClass =
        'w-full rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm text-slate-700 outline-none transition focus:border-blue-600 focus:ring-4 focus:ring-blue-100';

    const badgeEstado = (
        estado
    ) => {
        const clases = {
            PRESENTE:
                'bg-emerald-100 text-emerald-700',

            FALTA:
                'bg-red-100 text-red-700',

            TARDANZA:
                'bg-amber-100 text-amber-700',

            JUSTIFICADO:
                'bg-blue-100 text-blue-700',
        };

        return (
            <span
                className={`inline-flex rounded-full px-2.5 py-1 text-xs font-semibold ${
                    clases[
                        estado
                    ] ??
                    'bg-slate-100 text-slate-700'
                }`}
            >
                {estado?.replaceAll(
                    '_',
                    ' '
                )}
            </span>
        );
    };

    return (
        <AuthenticatedLayout
            header={
                <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
                    <div>
                        <h1 className="text-2xl font-bold text-slate-900">
                            Control de
                            asistencia
                        </h1>

                        <p className="mt-1 text-sm text-slate-500">
                            Registra la
                            asistencia de los
                            participantes de
                            esta sesión.
                        </p>
                    </div>

                    <div className="flex gap-2">
                        <Link
                            href={route(
                                'formacion.ediciones.show',
                                {
                                    formacionEdicion:
                                        edicion?.id,
                                }
                            )}
                            className="rounded-lg border border-slate-300 bg-white px-4 py-2.5 text-sm font-semibold text-slate-700 transition hover:bg-slate-50"
                        >
                            Volver a edición
                        </Link>
                    </div>
                </div>
            }
        >
            <Head title="Control de asistencia" />

            <div className="space-y-6">
                {/*
                ============================================================
                INFORMACIÓN DE LA SESIÓN
                ============================================================
                */}

                <section className="rounded-xl border border-slate-200 bg-white shadow-sm">
                    <div className="border-b border-slate-200 px-6 py-4">
                        <h2 className="font-bold text-slate-900">
                            Información de la
                            sesión
                        </h2>

                        <p className="mt-1 text-xs text-slate-500">
                            Datos de la
                            capacitación y
                            sesión seleccionada.
                        </p>
                    </div>

                    <div className="grid gap-5 p-6 sm:grid-cols-2 lg:grid-cols-4">
                        <div>
                            <div className="text-xs font-semibold uppercase tracking-wide text-slate-500">
                                Programa
                            </div>

                            <div className="mt-1 font-semibold text-slate-900">
                                {programa?.nombre ??
                                    '—'}
                            </div>
                        </div>

                        <div>
                            <div className="text-xs font-semibold uppercase tracking-wide text-slate-500">
                                Edición
                            </div>

                            <div className="mt-1 font-semibold text-slate-900">
                                {edicion?.nombre_edicion ??
                                    programa?.nombre ??
                                    '—'}
                            </div>
                        </div>

                        <div>
                            <div className="text-xs font-semibold uppercase tracking-wide text-slate-500">
                                Sesión
                            </div>

                            <div className="mt-1 font-semibold text-slate-900">
                                {sesion.numero
                                    ? `Sesión ${sesion.numero}`
                                    : 'Sesión'}

                                {sesion.nombre
                                    ? ` - ${sesion.nombre}`
                                    : ''}
                            </div>
                        </div>

                        <div>
                            <div className="text-xs font-semibold uppercase tracking-wide text-slate-500">
                                Fecha
                            </div>

                            <div className="mt-1 font-semibold text-slate-900">
                                {formatearFecha(
                                    sesion.fecha
                                )}
                            </div>

                            {sesion.hora_inicio && (
                                <div className="mt-0.5 text-xs text-slate-500">
                                    Hora:{' '}
                                    {formatearHora(
                                        sesion.hora_inicio
                                    )}
                                </div>
                            )}
                        </div>

                        {sesion.tema && (
                            <div className="sm:col-span-2 lg:col-span-4">
                                <div className="text-xs font-semibold uppercase tracking-wide text-slate-500">
                                    Tema
                                </div>

                                <p className="mt-1 whitespace-pre-line text-sm leading-6 text-slate-700">
                                    {
                                        sesion.tema
                                    }
                                </p>
                            </div>
                        )}
                    </div>
                </section>

                {/*
                ============================================================
                RESUMEN
                ============================================================
                */}

                <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-5">
                    <div className="rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
                        <div className="text-xs font-semibold uppercase text-slate-500">
                            Participantes
                        </div>

                        <div className="mt-2 text-2xl font-bold text-slate-900">
                            {
                                inscripciones.length
                            }
                        </div>
                    </div>

                    <div className="rounded-xl border border-emerald-100 bg-emerald-50 p-5">
                        <div className="text-xs font-semibold uppercase text-emerald-700">
                            Presentes
                        </div>

                        <div className="mt-2 text-2xl font-bold text-emerald-800">
                            {
                                resumen.PRESENTE
                            }
                        </div>
                    </div>

                    <div className="rounded-xl border border-red-100 bg-red-50 p-5">
                        <div className="text-xs font-semibold uppercase text-red-700">
                            Faltas
                        </div>

                        <div className="mt-2 text-2xl font-bold text-red-800">
                            {
                                resumen.FALTA
                            }
                        </div>
                    </div>

                    <div className="rounded-xl border border-amber-100 bg-amber-50 p-5">
                        <div className="text-xs font-semibold uppercase text-amber-700">
                            Tardanzas
                        </div>

                        <div className="mt-2 text-2xl font-bold text-amber-800">
                            {
                                resumen.TARDANZA
                            }
                        </div>
                    </div>

                    <div className="rounded-xl border border-blue-100 bg-blue-50 p-5">
                        <div className="text-xs font-semibold uppercase text-blue-700">
                            Justificados
                        </div>

                        <div className="mt-2 text-2xl font-bold text-blue-800">
                            {
                                resumen.JUSTIFICADO
                            }
                        </div>
                    </div>
                </div>

                {/*
                ============================================================
                ACCIONES MASIVAS
                ============================================================
                */}

                {inscripciones.length >
                    0 && (
                    <section className="rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
                        <div className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
                            <div>
                                <h2 className="font-bold text-slate-900">
                                    Acciones
                                    rápidas
                                </h2>

                                <p className="mt-1 text-xs text-slate-500">
                                    Puedes marcar
                                    a todos y luego
                                    modificar casos
                                    particulares.
                                </p>
                            </div>

                            <div className="flex flex-wrap gap-2">
                                <button
                                    type="button"
                                    onClick={() =>
                                        marcarTodos(
                                            'PRESENTE'
                                        )
                                    }
                                    className="rounded-lg bg-emerald-50 px-3 py-2 text-xs font-semibold text-emerald-700 transition hover:bg-emerald-100"
                                >
                                    Todos presentes
                                </button>

                                <button
                                    type="button"
                                    onClick={() =>
                                        marcarTodos(
                                            'FALTA'
                                        )
                                    }
                                    className="rounded-lg bg-red-50 px-3 py-2 text-xs font-semibold text-red-700 transition hover:bg-red-100"
                                >
                                    Todos falta
                                </button>

                                <button
                                    type="button"
                                    onClick={() =>
                                        marcarTodos(
                                            'TARDANZA'
                                        )
                                    }
                                    className="rounded-lg bg-amber-50 px-3 py-2 text-xs font-semibold text-amber-700 transition hover:bg-amber-100"
                                >
                                    Todos tardanza
                                </button>
                            </div>
                        </div>
                    </section>
                )}

                {/*
                ============================================================
                TABLA DE ASISTENCIA
                ============================================================
                */}

                <section className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm">
                    <div className="border-b border-slate-200 px-6 py-4">
                        <div className="flex items-center justify-between">
                            <div>
                                <h2 className="font-bold text-slate-900">
                                    Participantes
                                </h2>

                                <p className="mt-1 text-xs text-slate-500">
                                    Marca el estado
                                    de asistencia de
                                    cada estudiante.
                                </p>
                            </div>

                            <span className="rounded-full bg-blue-50 px-3 py-1 text-xs font-bold text-blue-700">
                                {
                                    inscripciones.length
                                }
                            </span>
                        </div>
                    </div>

                    {inscripciones.length ? (
                        <div className="overflow-x-auto">
                            <table className="min-w-full divide-y divide-slate-200">
                                <thead className="bg-slate-50">
                                    <tr>
                                        <th className="px-5 py-3 text-left text-xs font-bold uppercase tracking-wide text-slate-500">
                                            Estudiante
                                        </th>

                                        <th className="px-5 py-3 text-left text-xs font-bold uppercase tracking-wide text-slate-500">
                                            Estado
                                        </th>

                                        <th className="px-5 py-3 text-left text-xs font-bold uppercase tracking-wide text-slate-500">
                                            Hora
                                        </th>

                                        <th className="px-5 py-3 text-left text-xs font-bold uppercase tracking-wide text-slate-500">
                                            Observaciones
                                        </th>
                                    </tr>
                                </thead>

                                <tbody className="divide-y divide-slate-100 bg-white">
                                    {inscripciones.map(
                                        (
                                            inscripcion
                                        ) => {
                                            const estudiante =
                                                obtenerEstudiante(
                                                    inscripcion
                                                );

                                            const asistencia =
                                                asistencias.find(
                                                    (
                                                        item
                                                    ) =>
                                                        item.inscripcion_id ===
                                                        inscripcion.id
                                                );

                                            return (
                                                <tr
                                                    key={
                                                        inscripcion.id
                                                    }
                                                    className="transition hover:bg-slate-50"
                                                >
                                                    <td className="px-5 py-4">
                                                        <div className="font-semibold text-slate-900">
                                                            {nombreEstudiante(
                                                                estudiante
                                                            )}
                                                        </div>

                                                        <div className="mt-1 text-xs text-slate-500">
                                                            DNI:{' '}
                                                            {estudiante?.dni ??
                                                                '—'}
                                                        </div>

                                                        {estudiante?.codigo_postulante && (
                                                            <div className="text-xs text-slate-400">
                                                                Código:{' '}
                                                                {
                                                                    estudiante.codigo_postulante
                                                                }
                                                            </div>
                                                        )}
                                                    </td>

                                                    <td className="px-5 py-4">
                                                        <div className="space-y-2">
                                                            {badgeEstado(
                                                                asistencia?.estado
                                                            )}

                                                            <select
                                                                value={
                                                                    asistencia?.estado ??
                                                                    'PRESENTE'
                                                                }
                                                                onChange={(
                                                                    e
                                                                ) =>
                                                                    actualizarAsistencia(
                                                                        inscripcion.id,
                                                                        'estado',
                                                                        e
                                                                            .target
                                                                            .value
                                                                    )
                                                                }
                                                                className={
                                                                    inputClass
                                                                }
                                                            >
                                                                {estados.map(
                                                                    (
                                                                        estado
                                                                    ) => (
                                                                        <option
                                                                            key={
                                                                                estado
                                                                            }
                                                                            value={
                                                                                estado
                                                                            }
                                                                        >
                                                                            {estado.replaceAll(
                                                                                '_',
                                                                                ' '
                                                                            )}
                                                                        </option>
                                                                    )
                                                                )}
                                                            </select>
                                                        </div>
                                                    </td>

                                                    <td className="px-5 py-4">
                                                        <input
                                                            type="time"
                                                            value={
                                                                asistencia?.hora_registro ??
                                                                ''
                                                            }
                                                            onChange={(
                                                                e
                                                            ) =>
                                                                actualizarAsistencia(
                                                                    inscripcion.id,
                                                                    'hora_registro',
                                                                    e
                                                                        .target
                                                                        .value
                                                                )
                                                            }
                                                            className={
                                                                inputClass
                                                            }
                                                        />
                                                    </td>

                                                    <td className="px-5 py-4">
                                                        <input
                                                            type="text"
                                                            value={
                                                                asistencia?.observaciones ??
                                                                ''
                                                            }
                                                            placeholder="Observación opcional..."
                                                            onChange={(
                                                                e
                                                            ) =>
                                                                actualizarAsistencia(
                                                                    inscripcion.id,
                                                                    'observaciones',
                                                                    e
                                                                        .target
                                                                        .value
                                                                )
                                                            }
                                                            className={
                                                                inputClass
                                                            }
                                                        />
                                                    </td>
                                                </tr>
                                            );
                                        }
                                    )}
                                </tbody>
                            </table>
                        </div>
                    ) : (
                        <div className="p-12 text-center">
                            <div className="text-sm font-semibold text-slate-600">
                                No hay
                                participantes
                                registrados.
                            </div>

                            <div className="mt-1 text-xs text-slate-400">
                                Los estudiantes
                                inscritos en esta
                                capacitación
                                aparecerán aquí.
                            </div>
                        </div>
                    )}

                    {inscripciones.length >
                        0 && (
                        <div className="flex justify-end border-t border-slate-200 bg-slate-50 px-6 py-4">
                            <button
                                type="button"
                                onClick={
                                    guardarAsistencias
                                }
                                disabled={
                                    guardando
                                }
                                className="rounded-lg bg-blue-700 px-6 py-2.5 text-sm font-semibold text-white transition hover:bg-blue-800 disabled:cursor-not-allowed disabled:opacity-50"
                            >
                                {guardando
                                    ? 'Guardando...'
                                    : 'Guardar asistencia'}
                            </button>
                        </div>
                    )}
                </section>
            </div>
        </AuthenticatedLayout>
    );
}