<?php
require __DIR__ . '/../../../vendor/autoload.php';
!class_exists('Apartado') && require_once __DIR__ . '/apartadoModel.php';

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

class App
{
    public static function verificarSesionIniciada(): bool
    {
        if (session_status() == PHP_SESSION_NONE)
            session_start();

        if (isset($_SESSION[INDICE_SESION]) && $_SESSION[INDICE_SESION]->sesionActiva) {
            if (!empty($_SESSION[INDICE_SESION]->expireSession)) {
                $fechaActual = new DateTime();
                $fechaFormateada = date("Y-m-d H:i:s", $_SESSION[INDICE_SESION]->expireSession);
                $fechaExpiracion = new DateTime($fechaFormateada);

                if ($fechaActual > $fechaExpiracion) {
                    unset($_SESSION[INDICE_SESION]);
                    return false;
                }
            }

            return true;
        }

        return false;
    }

    public static function obtenerIdUsuario(): int
    {
        if (self::verificarSesionIniciada()) {
            return $_SESSION[INDICE_SESION]->id;
        }

        return 0;
    }

    public static function validarRoot(): bool
    {
        if (self::verificarSesionIniciada()) {
            $tipoPermiso = Permiso::validarTipoAcceso(self::obtenerIdUsuario(), 0);

            return $tipoPermiso->esRoot;
        }

        return false;
    }

    public static function verificarSesion()
    {
        if (!self::verificarSesionIniciada()) {
            http_response_code(403);
            echo json_encode((object)[
                'message' => 'No se ha iniciado sesión',
                'status' => 403,
            ]);
            exit();
        }
    }

    public static function obtenerFotoUsuario(): string
    {
        if (self::verificarSesionIniciada()) return $_SESSION[INDICE_SESION]->foto;
        return 'default.png';
    }

    public static function obtenerNombresUsuario(): string
    {
        if (self::verificarSesionIniciada()) return $_SESSION[INDICE_SESION]->nombres;
        return '';
    }

    public static function obtenerApellidosUsuario(): string
    {
        if (self::verificarSesionIniciada()) return $_SESSION[INDICE_SESION]->apellidos;
        return '';
    }

    public static function obtenerEmailUsuario(): string
    {
        if (self::verificarSesionIniciada()) return $_SESSION[INDICE_SESION]->email;
        return '';
    }

    public static function obtenerNombreCompletoUsuario(): string
    {
        if (self::verificarSesionIniciada()) return self::obtenerNombresUsuario() . ' ' . self::obtenerApellidosUsuario();
        return 'No se ha iniciado sesión';
    }

    public static function actualizarFotoUsuario($nombreArchivo)
    {
        if (self::verificarSesionIniciada()) $_SESSION[INDICE_SESION]->foto = $nombreArchivo;
    }

    public static function verificarAcceso($visualizacion = false): object
    {
        self::verificarSesion();

        $idUsuario = self::obtenerIdUsuario();

        $idApartado = null;

        if ($_SERVER['REQUEST_METHOD'] === 'GET') {
            isset($_GET['aid']) && $idApartado = base64_decode(urldecode($_GET['aid']));
        } else {
            $input = json_decode(file_get_contents('php://input'), true);
            !empty($_POST) && $input = $_POST;
            isset($input['aid']) && $idApartado = base64_decode(urldecode($input['aid']));
        }

        $respuesta = (object)[
            'status' => 500,
            'message' => 'Sin permiso',
        ];

        if (empty($idApartado)) {
            http_response_code($respuesta->status);
            echo json_encode($respuesta);
            exit();
        }

        !class_exists('Permiso') && require_once __DIR__ . '/../Models/permisoModel.php';

        $respuesta = Permiso::validarTipoAcceso($idUsuario, $idApartado);

        if ($respuesta->status != 200) {
            http_response_code($respuesta->status);
            echo json_encode($respuesta);
            exit();
        }

        $enMantenimiento = $respuesta->mantenimiento;

        if (intval($enMantenimiento) == 1) {
            http_response_code(503);
            echo json_encode((object)[
                'status' => 503,
                'message' => 'El apartado se encuentra en mantenimiento',
            ]);
            exit();
        }

        if (!in_array($respuesta->tipoPermiso, ['LECTURA', 'ESCRITURA'])) {
            http_response_code(401);
            echo json_encode((object)[
                'status' => 401,
                'message' => 'No tiene permiso para acceder a este apartado',
            ]);
            exit();
        }

        return $respuesta;
    }

    public static function obtenerUsername(): string
    {
        if (self::verificarSesionIniciada()) return $_SESSION[INDICE_SESION]->username;
        return '';
    }

    public static function iniciarSesionNET($token): object
    {
        $secretKey = 'seac.23$$Aluc4rDD3vC0nstrus3Rv1C3syYaNoSeMeOcurreNadaXD';
        $decoded = JWT::decode($token, new Key($secretKey, "HS256"));

        $keyNET = 'U2FsdGVkX19w0fv+1e2EHtlIjPo0rRsAw1mT6YV5cHh5iR6Ay9nRbC8o2e/Gl15D70/MlSrOtYebWYjD2Nx9gxwPs4MK4si63nQ7BXIz4HP6bI=';

        if ($decoded->netAuth == $keyNET) {
            $sesionIniciada = false;
            if (self::verificarSesionIniciada()) {
                $username = self::obtenerUsername();

                if ($username == $decoded->unique_name) {
                    $sesionIniciada = true;
                }
            }

            if (!$sesionIniciada) {
                $db = obtenerConexion();
                $solicitudUsuario = Usuario::obtenerPorUsername($db, $decoded->unique_name);

                if ($solicitudUsuario->status == 200 && !empty($solicitudUsuario->data)) {
                    $usuario = new Usuario();

                    $usuario->id = $solicitudUsuario->data->id;

                    $fechaExpira = $decoded->exp;

                    $solicitudSesion = $usuario->autenticarToken($db, $token, $fechaExpira);

                    if ($solicitudSesion->status == 200) {
                        $sesionIniciada = true;
                    }
                }
            }

            if ($sesionIniciada) {
                $baseURL = rtrim(dirname($_SERVER['PHP_SELF']), '/');

                if (!empty($decoded->screen) && !empty($decoded->contenedor)) {
                    $solicitudApartado = Apartado::obtenerPorArchivoModulo($decoded->screen, $decoded->contenedor);
                    // echo self::obtenerIdUsuario();die;
                    if ($solicitudApartado->status == 200) {
                        $apartado = $solicitudApartado->data;
                        
                        $baseURL = $baseURL . '?page=' . $apartado->nombreArchivo . '&aid=' . urlencode(base64_encode($apartado->id)) . '&mod=' . urlencode(base64_encode($apartado->contenedor)) . '&jwtU=' . urlencode(base64_encode(self::obtenerIdUsuario()));
                    }
                }

                header("Location: $baseURL");
                exit;
            }
        }

        return (object)[
            'status' => 401,
        ];
    }
}
