<?php
/**
 * Plugin Name: ICS Google Calendar
 * Description: Sincroniza tu calendario de Google sin necesidad de API key.
 * Version: 1.1
 * Author: Agencia Adhoc
 * Author URI: https://agenciaadhoc.com
 */

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

// Añade página de ajustes en el admin
add_action( 'admin_menu', function() {
    add_options_page(
        'ICS Calendar',
        'ICS Calendar',
        'manage_options',
        'ics-calendar',
        'ics_calendar_settings_page'
    );
} );

// Registra ajustes
add_action( 'admin_init', function() {
    register_setting( 'ics_calendar_settings', 'ics_calendar_url' );
    register_setting( 'ics_calendar_settings', 'ics_calendar_debug' );
} );

// Link de “Ajustes” en la lista de plugins
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), function( $links ) {
    $url = admin_url( 'options-general.php?page=ics-calendar' );
    array_unshift( $links, '<a href="' . esc_url( $url ) . '">Ajustes</a>' );
    return $links;
} );

// Página de ajustes
function ics_calendar_settings_page() {
    ?>
    <div class="wrap">
        <h1>Configuración del Calendario ICS</h1>
        <form method="post" action="options.php">
            <?php
            settings_fields( 'ics_calendar_settings' );
            do_settings_sections( 'ics_calendar_settings' );
            ?>
            <table class="form-table">
                <tr valign="top">
                    <th scope="row">URL del archivo .ics</th>
                    <td>
                        <input
                            type="text"
                            name="ics_calendar_url"
                            value="<?php echo esc_attr( get_option( 'ics_calendar_url' ) ); ?>"
                            size="70"
                        />
                    </td>
                </tr>
                <tr valign="top">
                    <th scope="row">Modo debug</th>
                    <td>
                        <label>
                            <input
                                type="checkbox"
                                name="ics_calendar_debug"
                                value="1"
                                <?php checked( get_option( 'ics_calendar_debug' ), 1 ); ?>
                            />
                            Mostrar array de eventos y código HTTP
                        </label>
                    </td>
                </tr>
            </table>
            <div style="background:#f1f1f1;padding:12px 20px;border-left:4px solid #007cba;margin-bottom:20px;">
                <p><strong>Shortcodes</strong></p>
                <p>Calendario con paginación (modo general).</p>
                <p style="font-size:16px;"><code>[ics_calendar]</code></p>

                <p>Calendario con posibilidad a limitación de meses UX/UI (modo visualmente atractivo).</p>
                <p style="font-size:16px;"><code>[ics_calendar_proximo meses=""]</code></p>
            </div>
            <?php submit_button('Guardar'); ?>
        </form>
        
    </div>
    <?php
}


// Shortcode [ics_calendar]
add_shortcode( 'ics_calendar', function() {
    $url   = get_option( 'ics_calendar_url', '' );
    $debug = get_option( 'ics_calendar_debug', false );

    if ( empty( $url ) ) {
        return '<p>Calendar not sync.</p>';
    }

    // Opciones para la petición HTTP
    $args = [
        'timeout'     => 15,
        'redirection' => 5,
        'sslverify'   => false,
        'headers'     => [
            'User-Agent' => 'WordPress/' . get_bloginfo( 'version' ),
        ],
    ];

    // Petición única
    $resp = wp_remote_get( $url, $args );
    if ( is_wp_error( $resp ) ) {
        return '<p>Error cargando el calendario: ' . esc_html( $resp->get_error_message() ) . '</p>';
    }

    $http_code = wp_remote_retrieve_response_code( $resp );
    $body      = wp_remote_retrieve_body( $resp );

    // Despliega líneas “folded” (comienzan con espacio)
    $body = preg_replace( "/\r?\n[ \t]/", '', trim( $body ) );

    // Parsear eventos
    $eventos = parsear_ics( $body );

    // Determinar mes/año por defecto
    if ( isset( $_GET['ics_month'], $_GET['ics_year'] ) ) {
        $mes  = intval( $_GET['ics_month'] );
        $anio = intval( $_GET['ics_year'] );
    } else {
        // Buscamos el primer evento >= hoy
        $hoy      = new DateTime( 'now', wp_timezone() );
        $firstEvt = null;
        foreach ( $eventos as $ev ) {
            if ( isset( $ev['start'] ) && $ev['start'] >= $hoy ) {
                if ( $firstEvt === null || $ev['start'] < $firstEvt ) {
                    $firstEvt = $ev['start'];
                }
            }
        }
        if ( $firstEvt ) {
            $mes  = intval( $firstEvt->format( 'n' ) );
            $anio = intval( $firstEvt->format( 'Y' ) );
        } else {
            $mes  = intval( date( 'n' ) );
            $anio = intval( date( 'Y' ) );
        }
    }

    // Encolar CSS
    wp_enqueue_style( 'ics-calendar-css', plugin_dir_url( __FILE__ ) . 'ics-calendar.css' );

    // Salida
    $output = '';

    if ( $debug ) {
        $output .= '<p><strong>HTTP status:</strong> ' . esc_html( $http_code ) . '</p>';
        $output .= '<pre style="background:#f7f7f7;border:1px solid #ccc;padding:10px;overflow:auto;">';
        $output .= esc_html( print_r( $eventos, true ) );
        $output .= '</pre>';
    }

    $output .= renderizar_calendario( $eventos, $mes, $anio );
    return $output;
} );

/**
 * Parsea un ICS y devuelve un array de eventos con 'summary', 'start', 'end'.
 */
function parsear_ics( $ics ) {
    $lines    = preg_split( '/\r?\n/', trim( $ics ) );
    $eventos  = [];
    $current  = null;

    foreach ( $lines as $line ) {
        $line = trim( $line );
        if ( $line === 'BEGIN:VEVENT' ) {
            $current = [];
        } elseif ( $line === 'END:VEVENT' ) {
            if ( ! empty( $current['start'] ) ) {
                $eventos[] = $current;
            }
            $current = null;
        } elseif ( $current !== null ) {
            if ( strpos( $line, 'SUMMARY:' ) === 0 ) {
                $current['summary'] = substr( $line, 8 );
            } elseif ( preg_match( '/^DTSTART(?:;[^:]+)?:/', $line ) ) {
                $current['start'] = formatear_fecha_ics( $line );
            } elseif ( preg_match( '/^DTEND(?:;[^:]+)?:/', $line ) ) {
                $current['end'] = formatear_fecha_ics( $line );
            }
        }
    }

    return $eventos;
}

/**
 * Convierte una línea DTSTART/DTEND a DateTime.
 */
function formatear_fecha_ics( $line ) {
    $parts = explode( ':', $line, 2 );
    if ( empty( $parts[1] ) ) {
        return null;
    }

    $val = trim( $parts[1] );

    // Si termina en Z, es UTC
    if ( str_ends_with( $val, 'Z' ) ) {
        $val = rtrim( $val, 'Z' );
        $dt  = DateTime::createFromFormat( 'Ymd\THis', $val, new DateTimeZone( 'UTC' ) );
        return $dt ? $dt->setTimezone( wp_timezone() ) : null;
    }

    if ( strpos( $val, 'T' ) !== false ) {
        return DateTime::createFromFormat( 'Ymd\THis', $val, wp_timezone() );
    }

    return DateTime::createFromFormat( 'Ymd', $val, wp_timezone() );
}


/**
 * Renderiza el mes del calendario con eventos.
 */
function renderizar_calendario( $eventos, $mes, $anio ) {
    $dias_semana = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ];
    $hoy_str     = date( 'Y-m-d' );
    $nombre_mes  = date_i18n( 'F Y', strtotime( "$anio-$mes-01" ) );

    // Navegación
    $prev_m = $mes === 1   ? 12         : $mes - 1;
    $prev_y = $mes === 1   ? $anio - 1  : $anio;
    $next_m = $mes === 12  ? 1          : $mes + 1;
    $next_y = $mes === 12  ? $anio + 1  : $anio;

    ob_start();

    echo '<div class="ics-calendar-container">';
    echo '<div class="nav-calendario" style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;">';
    echo '<a href="?ics_month=' . $prev_m . '&ics_year=' . $prev_y . '">&larr; Previous</a>';
    echo '<h2>' . esc_html( $nombre_mes ) . '</h2>';
    echo '<a href="?ics_month=' . $next_m . '&ics_year=' . $next_y . '">Next &rarr;</a>';
    echo '</div>';

    echo '<div class="cal-grid">';
    foreach ( $dias_semana as $d ) {
        echo '<div class="dia encabezado">' . esc_html( $d ) . '</div>';
    }

    $primer_dia    = date( 'N', strtotime( "$anio-$mes-01" ) );
    $dias_en_mes   = date( 't', strtotime( "$anio-$mes-01" ) );

    for ( $i = 1; $i < $primer_dia; $i++ ) {
        echo '<div class="dia vacio"></div>';
    }

    for ( $d = 1; $d <= $dias_en_mes; $d++ ) {
        $fecha  = sprintf( '%04d-%02d-%02d', $anio, $mes, $d );
        $classes = 'dia' . ( $fecha === $hoy_str ? ' hoy' : '' );
        echo '<div class="' . esc_attr( $classes ) . '">';
        echo '<div class="fecha">' . intval( $d ) . '</div>';

        foreach ( $eventos as $ev ) {
            if ( isset( $ev['start'] ) && $ev['start']->format( 'Y-m-d' ) === $fecha ) {
                $hora = $ev['start']->format( 'H:i' );
                echo '<div class="evento"><span class="hora">' . esc_html( $hora ) . '</span> ';
                echo '<span class="titulo">' . esc_html( $ev['summary'] ) . '</span></div>';
            }
        }

        echo '</div>';
    }

    echo '</div>'; // .cal-grid
    echo '</div>'; // .ics-calendar-container

    return ob_get_clean();
}

add_shortcode('ics_calendar_proximo', function ($atts) {
    wp_enqueue_style( 'ics-calendar-css', plugin_dir_url( __FILE__ ) . 'ics-calendar.css' );

    $atts = shortcode_atts(['meses' => 3], $atts);
    $meses = intval($atts['meses']);

    $url = get_option('ics_calendar_url', '');
    if (empty($url)) return '<p>Calendar not sync.</p>';

    $args = [
        'timeout' => 15,
        'sslverify' => false,
        'headers' => ['User-Agent' => 'WordPress/' . get_bloginfo('version')],
    ];

    $resp = wp_remote_get($url, $args);
    if (is_wp_error($resp)) return '<p>Error: ' . esc_html($resp->get_error_message()) . '</p>';

    $body = preg_replace("/\r?\n[ \t]/", '', trim(wp_remote_retrieve_body($resp)));
    $eventos = parsear_ics($body);

    $hoy = new DateTime('now', wp_timezone());
    $limite = (clone $hoy)->modify('+' . $meses . ' months');

    $filtrados = array_filter($eventos, function ($ev) use ($hoy, $limite) {
        return isset($ev['start']) && $ev['start'] >= $hoy && $ev['start'] <= $limite;
    });

    usort($filtrados, function ($a, $b) {
        return $a['start'] <=> $b['start'];
    });

    ob_start();
    echo '<div class="ics-prox-grid">';
    foreach ($filtrados as $ev) {
        $fecha = $ev['start']->format('d');
        $mes = strtoupper($ev['start']->format('M'));
        $titulo = esc_html($ev['summary']);
        $rango = $ev['start']->format('F d') . (isset($ev['end']) ? ' - ' . $ev['end']->format('d, Y') : '');
        echo "<div class='ics-prox-event'>
                <div class='ics-prox-date'>
                    <span class='ics-prox-day'>$fecha</span>
                    <span class='ics-prox-month'>$mes</span>
                </div>
                <div class='ics-prox-details'>
                    <strong class='ics-prox-title'>$titulo</strong><br>
                    <small class='ics-prox-range'>$rango</small>
                </div>
              </div>";
    }
    echo '</div>';
    return ob_get_clean();
});

