<?php
/**
 *
 * @package   rinnovo_booking
 * @author    Stefano Pacetti
 * @copyright 2022-2122 ThinkNow.it
 * @license   GPL-2.0-or-later
 * @version   2.1.1
 *
 * @wordpress-plugin
 * Plugin Name:       Rinnovo Booking
 * Plugin URI:        https://plugin.webevent.it/rinnovo_booking/
 * Description:       Rinnovo patente online per autoscuole
 * Version:           2.1.1
 * Requires at least: 6.0
 * Requires PHP:      8.1
 * Author:            Stefano Pacetti
 * Author URI:        https://www.thinknow.it/
 * Text Domain:       thinknow
 * License:           GPL v2 or later
 * License URI:       http://www.gnu.org/licenses/gpl-2.0.txt
 * Update URI:        https://plugin.webevent.it/rinnovo_booking/
 */

 define('RINNOVO_BOOKING_VERSION', '2.1.1');


if ( !defined('ABSPATH') ) {
    die;
}

include_once 'config/config.php';
include_once 'config/autoload.php';
require 'update/plugin-update-checker.php';

use YahnisElsts\PluginUpdateChecker\v5\PucFactory;
use RinnovoBooking\Core\AdminMenu;
use RinnovoBooking\Core\RinnovoBookingInit;
use RinnovoBooking\Core\RinnovoBookingService;
use RinnovoBooking\Core\IPatenteService;
use RinnovoBooking\Core\CloudHandler;
use RinnovoBooking\Core\EmailService;
use RinnovoBooking\Core\RinnovoBookingShortcode;

AdminMenu::get_instance();
new RinnovoBookingShortcode();


register_activation_hook(__FILE__, [RinnovoBookingInit::class, 'RinnovoBookingActivate']);
register_deactivation_hook( __FILE__, [RinnovoBookingInit::class, 'RinnovoBookingDeactivate']);
register_uninstall_hook(__FILE__, [RinnovoBookingInit::class, 'RinnovoBookingUninstall']);

add_action('wp_enqueue_scripts', 'rinnovo_booking_script');
function rinnovo_booking_script() {
    wp_enqueue_style('rinnovo_booking-styles', plugin_dir_url(__FILE__) . 'css/rinnovo_booking.css');
    wp_enqueue_script('rinnovo_booking-scripts', plugin_dir_url(__FILE__) . 'js/rinnovo_booking.js', ['jquery'], null, true);
}

$myUpdateChecker = PucFactory::buildUpdateChecker(RINNOVOBOOKINGSERVERPLUGIN.RINNOVOBOOKINGPREFIX.'/'.RINNOVOBOOKINGPREFIX.'.json', __FILE__, RINNOVOBOOKINGPREFIX);



#####################################################################################################################
#               SISTEMA DI GESTIONE DEL CALENDARIO               SISTEMA DI GESTIONE DEL CALENDARIO                 #
#####################################################################################################################


/**
 * Recupera le disponibilità dal database
 * @param mixed $sede
 * @return array|object|null
 */
function rinnovo_booking_get_availability($sede) {
    global $wpdb;
    $table_name = $wpdb->prefix . RINNOVOBOOKINGPREFIX . '_time_slots';
    // Aggiungi una condizione per filtrare per sede
    $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE idsede = %s", $sede), ARRAY_A);
    return $results;
}


/**
 * Recupera gli appuntamenti dal database
 * @return array|object|null
 */
function rinnovo_booking_get_busy() {
    global $wpdb;
    $table_name = $wpdb->prefix.RINNOVOBOOKINGPREFIX.'_bookings';
    $today = date('Y-m-d');
    $results = $wpdb->get_results("SELECT * FROM $table_name WHERE `date` >= '$today'", ARRAY_A);
    return $results;
}


/**
 * Recupera l'apertura dal database
 * @param mixed $sede
 * @return array|object|null
 */
function rinnovo_booking_get_apertura($sede) {
    global $wpdb;
    $table_name = $wpdb->prefix . RINNOVOBOOKINGPREFIX . '_slots_except';
    $oggi = date('Y-m-d');
    $query = "SELECT * FROM $table_name WHERE idsede = '$sede' AND stato = 'open' AND day_of_week >= '$oggi' ORDER BY day_of_week ASC";
    $apertura = $wpdb->get_results($query, ARRAY_A);
    return $apertura;
}


/**
 * Recupera la chiusura dal database
 * @param mixed $sede
 * @return array|object|null
 */
function rinnovo_booking_get_chiusura($sede) {
    global $wpdb;
    $table_name = $wpdb->prefix . RINNOVOBOOKINGPREFIX . '_slots_except';
    $query = "SELECT * FROM $table_name WHERE idsede = '$sede' AND stato = 'close'";
    $chiusura = $wpdb->get_results($query, ARRAY_A);    
    return $chiusura;
}


#########################################################################################################################################
#        LICENZA       LICENZA       LICENZA       LICENZA       LICENZA       LICENZA       LICENZA       LICENZA       LICENZA        #
#########################################################################################################################################


    /**
     * Funzione per verificare la licenza tramite API
     * @return bool
     */
     function rinnovo_booking_verify_license() {
        // Recupera la chiave di licenza salvata
        global $wpdb, $dataApi;
        $table_name = $wpdb->prefix.RINNOVOBOOKINGPREFIX;
        $mia_licenza = $wpdb->get_results("SELECT `op_val` FROM $table_name WHERE `operazione`= 'licenza'");

        // Imposta l'URL dell'API (sostituisci con l'URL del tuo server Laravel o API di verifica)
        $api_url = RINNOVOBOOKINGAPI;
        $license_key = $mia_licenza['0']->op_val;
        $dominio = $_SERVER['SERVER_NAME'];
        $api_key = RINNOVOBOOKINGTOKEN;

        $body = [
            'license_key' => $license_key,
            'domain' => $dominio,
        ];

        // Verifica la licenza tramite API
        $RinnovoBookingService = new RinnovoBookingService();
        $response = $RinnovoBookingService->rinnovo_booking_CURLBearer($api_url,$api_key, $body );
        $dataApi = json_decode($response, true);

        // Verifica lo stato della licenza
        if (isset($dataApi['status']) && $dataApi['status'] == 'valid') {
            return true; // Licenza valida
        }

        return false; // Licenza non valida
    }



/**
 * Verifica la licenza del plugin
 * @return void
 */
add_action('admin_init', 'rinnovo_booking_check_license');
function rinnovo_booking_check_license() {
    if (!rinnovo_booking_verify_license()) {
        add_action('admin_notices', 'rinnovo_booking_license_error_notice');
    }
}


/**
 * Mostra un avviso se la licenza non è valida
 * @return void
 */
function rinnovo_booking_license_error_notice() {
    ?>
    <div class="notice notice-error">
        <p><?php _e('La tua licenza del plugin Rinnovo Booking non è valida o è scaduta. Si prega di inserire una licenza valida.', 'rinnovo_booking-textdomain'); ?></p>
    </div>
    <?php
}


/**
 * Disabilita le funzionalità del plugin nel frontend
 * @return void
 */
function rinnovo_booking_disable_frontend() {
    wp_die('Il plugin è disabilitato perché la licenza non è valida o è scaduta.','Licenza Non Valida',array('response' => 403));
}


/**
 * Verifica i servizi tramite API
 * @return array|bool
 */
function rinnovo_booking_verify_services() {
    // Recupera la chiave di licenza salvata
    global $wpdb, $dataApi;
    $table_name = $wpdb->prefix.RINNOVOBOOKINGPREFIX;
    $mia_licenza = $wpdb->get_results("SELECT `op_val` FROM $table_name WHERE `operazione`= 'licenza'");

    // Imposta l'URL dell'API (sostituisci con l'URL del tuo server Laravel o API di verifica)
    $api_url = RINNOVOBOOKINGAPI;
    $license_key = $mia_licenza['0']->op_val;
    $dominio = $_SERVER['SERVER_NAME'];
    $api_key = RINNOVOBOOKINGTOKEN;

    $body = [
        'license_key' => $license_key,
        'domain' => $dominio,
    ];

    $RinnovoBookingService = new RinnovoBookingService();
    $response = $RinnovoBookingService->rinnovo_booking_CURLBearer($api_url,$api_key, $body );
    $dataApi = json_decode($response, true);

    // Verifica lo stato della licenza
    if (isset($dataApi['status']) && $dataApi['status'] == 'valid') {
        return $dataApi['servizi']; // elenco servizi disponibili
    }

    return false; // Licenza non valida
}



#######################################################################################################################
#       AJAX       AJAX       AJAX       AJAX       AJAX       AJAX       AJAX       AJAX       AJAX       AJAX       #
#######################################################################################################################

// Funzione per gestire le prenotazioni (AJAX)
add_action('wp_ajax_rinnovo_booking_handle_booking', 'rinnovo_booking_handle_booking');
add_action('wp_ajax_nopriv_rinnovo_booking_handle_booking', 'rinnovo_booking_handle_booking');
function rinnovo_booking_handle_booking() {
    // Recupera i dati inviati dalla richiesta AJAX
    $date = sanitize_text_field($_POST['date']);
    $time = sanitize_text_field($_POST['time']);

    // Logica per salvare la prenotazione nel database
    global $wpdb;
    $table_name = $wpdb->prefix.RINNOVOBOOKINGPREFIX.'_bookings';

    $wpdb->insert($table_name, array(
        'date' => $date,
        'time' => $time,
        'created_at' => current_time('mysql')
    ));

    wp_send_json_success(array('message' => 'Prenotazione confermata!'));
}


add_action('wp_ajax_rinnovo_booking_get_time_slots', 'rinnovo_booking_get_time_slots');
add_action('wp_ajax_nopriv_rinnovo_booking_get_time_slots', 'rinnovo_booking_get_time_slots');
function rinnovo_booking_get_time_slots() {
    global $wpdb;
    $day_of_week = sanitize_text_field($_POST['day_of_week']);
    $table_name = $wpdb->prefix . RINNOVOBOOKINGPREFIX . '_time_slots';

    $results = $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM $table_name WHERE day_of_week = %s",
        $day_of_week
    ));

    $slots = [];
    foreach ($results as $row) {
        $bookings = $row->date;
        $booked_times = array_column($bookings, 'time');
        $is_booked = in_array($row->start_time, $booked_times);

        $slots[] = [
            'start_time' => $row->start_time,
            'end_time' => $row->end_time,
            'minutes_slots' => $row->minutes_slots,
            'max_slots' => $row->max_slots,
            'is_booked' => $is_booked,
            'services' => json_decode($row->services)
        ];
    }

    wp_send_json_success(['slots' => $slots]);
}



#########################################################################################################################################
#       SHORTCODE       SHORTCODE       SHORTCODE       SHORTCODE       SHORTCODE       SHORTCODE       SHORTCODE       SHORTCODE       #
#########################################################################################################################################


#########################################################################################
#                                                                                       #
#   Genera il calendario e la pagina di conferma prenotazione del plugin                #
#   Descrizione: Genera il frontend del plugin                                          #
#                                                                                       #
#   Funzionante al 01/09/2024                                                           #
#   Revisione 1.0 funzionante al 01/09/2024                                             #
#                                                                                       #
#   shotcode : [rinnovo_booking_calendar sede="sede" gruppo="gruppo"]                   #
#                                                                                       #
#########################################################################################
add_shortcode('rinnovo_booking_calendar', 'rinnovo_booking_display_calendar');
function rinnovo_booking_display_calendar($atts){
    ob_start(); // attivazione buffer di scrittura. Consente il posizionamento del plugin nella pagina.

    extract(
        shortcode_atts(array(
            'sede' => '',
            'gruppo' => '',
        ), $atts, 'rinnovo_booking_calendar')
    );

    global $wpdb;

    // Se la licenza non è valida, restituisci un messaggio di errore o vuoto
    if (!rinnovo_booking_verify_license()) {
        return '<p>' . 'La licenza del plugin non è valida o è scaduta. Si prega di aggiornare la licenza.' . '</p>';
    }

    // verifica le opzioni del sistema
    $RinnovoBookingService = new RinnovoBookingService();
    $opzioniSistema = $RinnovoBookingService->vediOpzioniSistema($sede);

    // recupera il ritardo della sede
    $table_sedi = $wpdb->prefix . RINNOVOBOOKINGPREFIX . '_sedi';
    $ritardoSede = $wpdb->get_var($wpdb->prepare("SELECT ritardo_minuti FROM $table_sedi WHERE idsede = %s", $sede));
    $ritardoSede = $ritardoSede ? intval($ritardoSede) : 0;

    // verifica se il servizio ipatente è attivo
    $servizi = rinnovo_booking_verify_services();
    if (in_array('ipatente', $servizi) || in_array('ipatentebutton', $servizi)) { 
        $iPatenteService = new iPatenteService();
        $iPanteArray = $iPatenteService->getGenerateCalendar($sede, $gruppo);

        $disponibilita = $iPanteArray['disponibilita'];
        $occupati = $iPanteArray['occupati'];
        $apertura = $iPanteArray['apertura'];
        $chiusura = $iPanteArray['chiusura'];
    } else {
        // Passa la sede alla funzione per ottenere le disponibilità
        $disponibilita = rinnovo_booking_get_availability($sede);
        $occupati = rinnovo_booking_get_busy();
        $apertura = rinnovo_booking_get_apertura($sede);
        $chiusura = rinnovo_booking_get_chiusura($sede);
    }   

    wp_localize_script('rinnovo_booking-scripts', 'cbpData', array(
        'availability' => $disponibilita, // Modificato
        'busy' => $occupati,
        'sede' => $sede,
        'gruppo' => $gruppo,
        'apertura' => $apertura,
        'chiusura' => $chiusura,
        'ritardo_minuti' => $ritardoSede
    ));

    try {
        // pagina di conferma prenotazione
        if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['confirm_booking'])) {

            // Associa il testo corrispondente al tipo_visita
            $tipo_visita_testo = '';
            switch($_POST['tipo_visita']) {
                case 'rinnovo':
                    $tipo_visita_testo = 'Rinnovo Patente';
                    break;
                case 'conseguimento': 
                    $tipo_visita_testo = 'Conseguimento Patente';
                    break;
                case 'porto_d_armi':
                    $tipo_visita_testo = 'Porto d\'Armi';
                    break;
                case 'estensione':
                    $tipo_visita_testo = 'Estensione Patente';
                    break;
                case 'duplicato_documento':
                    $tipo_visita_testo = 'Duplicato Documento';
                    break;
                case 'rinnovo_patente_nautica':
                    $tipo_visita_testo = 'Rinnovo Patente Nautica';
                    break;
            }

            $miaPagina = plugin_dir_path(__FILE__) . 'html/confermaprenotazione.php';

            $sede = esc_html($sede);
            $gruppo = esc_html($gruppo);
            $tipo_visita = esc_html($_POST['tipo_visita']);
            $tipo_visita_testo = esc_html($tipo_visita_testo);
            $PrenotaData = esc_html($_POST['PrenotaData']);
            $PrenotaOra = esc_html($_POST['PrenotaOra']);
            $cognome = esc_html($_POST['cognome']);
            $nome = esc_html($_POST['nome']);
            $email = esc_html($_POST['email']);
            $telefono = esc_html($_POST['telefono']);
            $npatente = esc_html($_POST['npatente']);
            $indirizzo = esc_html($_POST['indirizzo']);
            $obbligofotofirmata = in_array('obbligofotofirmata', $opzioniSistema) ? 'true' : 'false';

            // verifica dei servizi attivi
            $servizi = rinnovo_booking_verify_services();
            // Inserisce fotofirma se il servizio è attivo
            if (in_array('fotofirma', $servizi)) {
                $fotofirmaFile = plugin_dir_path(__FILE__) . 'html/fotofirma.php'; //Attiva il box per l'inserimento della firma e della foto.
            } else if (in_array('fotofirmalite', $servizi)){
                $fotofirmaFile = plugin_dir_path(__FILE__) . 'html/fotofirmalite.php'; //Attiva il box per l'inserimento della firma e della foto e della foto patente.
            } else if (in_array('fotofirmafull', $servizi)){
                $fotofirmaFile = plugin_dir_path(__FILE__) . 'html/fotofirmafull.php'; //Attiva il box per il l'inserimento della firma ed il caricamento delle foto di tutti i documenti.
            } else {
                $fotofirmaFile = '';
            }

            include $miaPagina;

        // codice per generare la prenotazione
        } else if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['send_booking'])) {

            /**
             * Inserimento prenotazione nel database
             */
            $RinnovoBookingService->registerOnDatabase($_POST); 

            /**
             * Inserimento prenotazione in iPatente
             */
            if (in_array('ipatente', $servizi)) {
                $iPatenteService = new iPatenteService();
                $iPanteArray = $iPatenteService->registerOnIPatente($_POST);
            }

            /**
             * Invio email al cliente e all'admin
             */
            $EmailService = new EmailService();
            if (in_array('emailautoscuola', $opzioniSistema)) {
                $attachments = $EmailService->generateAttachments($_FILES, $_POST["firma"]);
                $resultEmailAdmin = $EmailService->sendAdminEmail($sede, $_POST, $attachments);
            } else {
                $resultEmailAdmin = true;
            }

            if (in_array('emailcliente', $opzioniSistema)) {
                if (in_array('emailbutton', $servizi)) {
                    $resultEmailClient = $EmailService->sendInfoEmail($sede, $_POST,  $attachments);
                } else {
                    $resultEmailClient = $EmailService->sendClientEmail($sede, $_POST,  $attachments);
                }
            } else {
                $resultEmailClient = true;
            }

            // recupera i testi finali
            $table_name = $wpdb->prefix.RINNOVOBOOKINGPREFIX;
            $testoFinale = $wpdb->get_results("SELECT `op_val` FROM $table_name WHERE `operazione`= 'testofinale'");  
            $testoFinaleSettings = json_decode($testoFinale['0']->op_val);

            if ($resultEmailClient == true && $resultEmailAdmin == true) {
                $risposta = $testoFinaleSettings->titoloConvalida;
                $rispostaTesto = $testoFinaleSettings->testoConvalida;
                $rispostaStyle = 'success';
            } else {
                $risposta = $testoFinaleSettings->erroreConvalida;
                $rispostaTesto = '';
                $rispostaStyle = 'danger';
            }

            /**
             * Caricamento file su cloud
             */
            if (in_array('cloud', $servizi)) {
                $CloudHandler = new CloudHandler();
                $nomeCartellaUtente = $_POST['cognome'].'_'.$_POST['nome'];
                $nomeCartellaData = $_POST['PrenotaData'];

                if (isset($attachments['foto.jpg'])) {
                    $CloudHandler->handleCloud($attachments['foto.jpg'],$nomeCartellaData, $nomeCartellaUtente, $nomeCartellaUtente.'_foto', $sede);
                }
                if (isset($attachments["firma.jpg"])) {                    
                    $CloudHandler->handleCloud($attachments['firma.jpg'],$nomeCartellaData, $nomeCartellaUtente, $nomeCartellaUtente.'_firma', $sede);
                }
                if (isset($attachments['fotofirma.jpg'])) {
                    $CloudHandler->handleCloud($attachments['fotofirma.jpg'],$nomeCartellaData, $nomeCartellaUtente, $nomeCartellaUtente.'_fotofirma', $sede);
                }
                if (isset($attachments['fotoPatenteFronte.jpg'])) {
                    $CloudHandler->handleCloud($attachments['fotoPatenteFronte.jpg'],$nomeCartellaData, $nomeCartellaUtente, $nomeCartellaUtente.'_fotoPatenteFronte', $sede);
                }
                if (isset($attachments['fotoPatenteRetro.jpg'])) {
                    $CloudHandler->handleCloud($attachments['fotoPatenteRetro.jpg'],$nomeCartellaData, $nomeCartellaUtente, $nomeCartellaUtente.'_fotoPatenteRetro', $sede);
                }
                if (isset($attachments['fotoDocumentoFronte.jpg'])) {
                    $CloudHandler->handleCloud($attachments['fotoDocumentoFronte.jpg'],$nomeCartellaData, $nomeCartellaUtente, $nomeCartellaUtente.'_fotoDocumentoFronte', $sede);
                }
                if (isset($attachments['fotoDocumentoRetro.jpg'])) {
                    $CloudHandler->handleCloud($attachments['fotoDocumentoRetro.jpg'],$nomeCartellaData, $nomeCartellaUtente, $nomeCartellaUtente.'_fotoDocumentoRetro', $sede);
                }
                if (isset($attachments['fotoPermessoSoggiornoFronte.jpg'])) {
                    $CloudHandler->handleCloud($attachments['fotoPermessoSoggiornoFronte.jpg'],$nomeCartellaData, $nomeCartellaUtente, $nomeCartellaUtente.'_fotoPermessoSoggiornoFronte', $sede);
                }
                if (isset($attachments['fotoPermessoSoggiornoRetro.jpg'])) {
                    $CloudHandler->handleCloud($attachments['fotoPermessoSoggiornoRetro.jpg'],$nomeCartellaData, $nomeCartellaUtente, $nomeCartellaUtente.'_fotoPermessoSoggiornoRetro', $sede);
                }
            }

            // Cancella i file usati per inviare le email
            if (isset($uploadFoto['file'])) { unlink($uploadFoto['file']); }
            if (isset($uploadFirma['file'])) { unlink($uploadFirma['file']); }
            if (isset($uploadPatenteFronte['file'])) { unlink($uploadPatenteFronte['file']); } 
            if (isset($uploadPatenteRetro['file'])) { unlink($uploadPatenteRetro['file']); }
            if (isset($uploadDocumentoFronte['file'])) { unlink($uploadDocumentoFronte['file']); }
            if (isset($uploadDocumentoRetro['file'])) { unlink($uploadDocumentoRetro['file']); }
            if (isset($uploadPermessoSoggiornoFronte['file'])) { unlink($uploadPermessoSoggiornoFronte['file']); }
            if (isset($uploadPermessoSoggiornoRetro['file'])) { unlink($uploadPermessoSoggiornoRetro['file']); }

            // rimuove la modifica della directory di upload
            remove_filter( 'upload_dir', '__return_null' );

            // carica pagina di risposta
            $miaPagina = plugin_dir_path(__FILE__) . 'html/rispostaprenotazione.php';
            $risposta = esc_html($risposta);
            $rispostaTesto = esc_html($rispostaTesto);
            $rispostaStyle = esc_html($rispostaStyle);
            include $miaPagina;

        // carica il calendario iniziale
        } else {
            $miaPagina = plugin_dir_path(__FILE__) . 'html/calendario.php';
            $sede = esc_html($sede);
            $gruppo = esc_html($gruppo);
            include $miaPagina;
        }        
    } catch (error $e) {
        echo "Errore creazione elenco: ".$e->getMessage()."\n";
    }

    return ob_get_clean(); // scrittura dal buffer nel punto dello shortcode
} //function rinnovo_booking_display_calendar($atts)
