<?php

/**
 * Plugin Name: Selection Speech TTS
 * Description: A simple plugin that lets users highlight text and hear it spoken aloud using a draggable mini-player. No TTS API required.
 * Version: 3.1
 * Author: Computing For All
 * License: GPLv2 or later
 */
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
if ( function_exists( 'sst_fs' ) ) {
    sst_fs()->set_basename( false, __FILE__ );
} else {
    /**
     * DO NOT REMOVE THIS IF, IT IS ESSENTIAL FOR THE
     * `function_exists` CALL ABOVE TO PROPERLY WORK.
     */
    if ( !function_exists( 'sst_fs' ) ) {
        function sst_fs() {
            global $sst_fs;
            if ( isset( $sst_fs ) && !is_object( $sst_fs ) ) {
                return false;
            }
            if ( !isset( $sst_fs ) ) {
                // Include Freemius SDK.
                require_once dirname( __FILE__ ) . '/vendor/freemius/start.php';
                $sst_fs = fs_dynamic_init( array(
                    'id'             => '19882',
                    'slug'           => 'selection-speech-tts',
                    'type'           => 'plugin',
                    'public_key'     => 'pk_1be2363524cfae1369d2367a38e31',
                    'is_premium'     => false,
                    'is_org_compliant' => true,
                    'has_paid_plans'   => false,
                    'menu'           => array(
                        'slug'    => 'selection-speech-tts',
                        'support' => false,
                        'account' => false,
                        'pricing' => false,
                        'parent'  => array(
                            'slug' => 'options-general.php',
                        ),
                    ),
                    'is_live'        => true,
                ) );
            }
            return $sst_fs;
        }

        sst_fs();
        do_action( 'sst_fs_loaded' );
        if ( function_exists( 'sst_fs' ) ) {
        }
    }
}
/**
 * Define constants
 */
define( 'SSTTS_VERSION', '3.1' );
define( 'SSTTS_TABLE', $GLOBALS['wpdb']->prefix . 'sstts_usage' );
/**
 * Enqueue frontend assets
 */
function sstts_enqueue_assets() {
    $url = plugin_dir_url( __FILE__ );
    wp_enqueue_style(
        'sstts-style',
        $url . 'assets/sstts.css',
        array(),
        SSTTS_VERSION
    );
    wp_enqueue_script(
        'sstts-script',
        $url . 'assets/sstts.js',
        array(),
        SSTTS_VERSION,
        true
    );
    $is_paying_user = false;
    if ( function_exists( 'sst_fs' ) ) {
    }
    wp_localize_script( 'sstts-script', 'sstts_data', [
        'is_paying_user' => $is_paying_user,
    ] );
}

add_action( 'wp_enqueue_scripts', 'sstts_enqueue_assets' );
/**
 * Plugin activation
 */
register_activation_hook( __FILE__, 'sstts_activate' );

/**
 * Activation: create table and seed options.
 * Supports single-site and multisite network activation.
 */
function sstts_activate( $network_wide ) {
    if ( is_multisite() && $network_wide ) {
        // Run on every site in the network
        $site_ids = get_sites( array( 'fields' => 'ids' ) );
        foreach ( $site_ids as $site_id ) {
            switch_to_blog( $site_id );
            sstts_install_for_current_blog();
            restore_current_blog();
        }
    } else {
        // Single site
        sstts_install_for_current_blog();
    }
}

/**
 * Create/upgrade schema for the current blog.
 */
function sstts_install_for_current_blog() {
    global $wpdb;

    $table           = $wpdb->prefix . 'sstts_usage';
    $charset_collate = $wpdb->get_charset_collate();

    require_once ABSPATH . 'wp-admin/includes/upgrade.php';

    // IMPORTANT: no IF NOT EXISTS in dbDelta() SQL
    $sql = "CREATE TABLE {$table} (
        log_date DATE NOT NULL,
        plays INT UNSIGNED NOT NULL DEFAULT 0,
        restarts INT UNSIGNED NOT NULL DEFAULT 0,
        PRIMARY KEY  (log_date)
    ) {$charset_collate};";

    dbDelta( $sql );

    // Seed options if not present
    add_option( 'sstts_total_plays', 0 );
    add_option( 'sstts_total_restarts', 0 );

    // Track schema version for future upgrades
    update_option( 'sstts_db_version', '1' );
}

/**
 * Optional: run schema upgrades in future versions.
 */
add_action( 'plugins_loaded', function () {
    $current = get_option( 'sstts_db_version', '1' );
    // if ( version_compare( $current, '2', '<' ) ) {
    //     // put dbDelta() with new schema here
    //     update_option( 'sstts_db_version', '2' );
    // }
} );

/**
 * Plugin uninstall
 */

sst_fs()->add_action( 'after_uninstall', 'sstts_uninstall_cleanup' );
register_uninstall_hook( __FILE__, 'sstts_uninstall_cleanup' );

function sstts_uninstall_cleanup() {
    if ( is_multisite() ) {
        $site_ids = get_sites( array( 'fields' => 'ids' ) );
        foreach ( $site_ids as $site_id ) {
            switch_to_blog( $site_id );
            sstts_uninstall_for_current_blog();
            restore_current_blog();
        }
    } else {
        sstts_uninstall_for_current_blog();
    }
}

function sstts_uninstall_for_current_blog() {
    global $wpdb;
    $table = $wpdb->prefix . 'sstts_usage';
    $wpdb->query( "DROP TABLE IF EXISTS `{$table}`" );
    delete_option( 'sstts_total_plays' );
    delete_option( 'sstts_total_restarts' );
    delete_option( 'sstts_db_version' );
}

/**
 * Admin menu
 */
add_action( 'admin_menu', function () {
    add_options_page(
        'Selection Speech TTS Stats',
        'Selection Speech TTS',
        'manage_options',
        'selection-speech-tts',
        'sstts_render_stats_page'
    );
} );






/**
 * Download CSV
 */
add_action( 'admin_post_sstts_download', 'sstts_download_csv' );
function sstts_download_csv() {
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_die( esc_html__( 'Unauthorized user', 'selection-speech-tts' ) );
    }

    check_admin_referer( 'sstts_download' );
    global $wpdb;
    while ( ob_get_level() ) {
        ob_end_clean();
    }
    nocache_headers();
    header( 'Content-Type: text/csv; charset=utf-8' );
    header( 'Content-Disposition: attachment; filename=sstts-usage.csv' );
    $out = fopen( 'php://output', 'w' );
    fputcsv( $out, ['log_date', 'plays', 'restarts'] );
    $rows = $wpdb->get_results( "SELECT * FROM `" . esc_sql( SSTTS_TABLE ) . "` ORDER BY log_date ASC" );
    foreach ( $rows as $r ) {
        fputcsv( $out, [$r->log_date, $r->plays, $r->restarts] );
    }

    // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
    fclose( $out );
    exit;
}

add_action( 'admin_post_sstts_clear_table', 'sstts_clear_table' );
function sstts_clear_table() {
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_die( esc_html__( 'Unauthorized user', 'selection-speech-tts' ) );
    }

    check_admin_referer( 'sstts_clear' );
    global $wpdb;
    $wpdb->query( 'TRUNCATE TABLE `' . esc_sql( SSTTS_TABLE ) . '`' );
    wp_safe_redirect( admin_url( 'options-general.php?page=selection-speech-tts&cleared=1' ) );
    exit;
}

/**
 * Admin stats page
 */
function sstts_render_stats_page() {
    global $wpdb;
    $fs = ( function_exists( 'sst_fs' ) ? sst_fs() : false );
    $table = esc_sql( SSTTS_TABLE );
    $totals = $wpdb->get_row( "SELECT SUM(plays) AS p, SUM(restarts) AS r FROM `{$table}`" );

    $total_plays    = isset( $totals->p ) ? (int) $totals->p : 0;
    $total_restarts = isset( $totals->r ) ? (int) $totals->r : 0;

    $rows = $wpdb->get_results( "SELECT * FROM `{$table}` ORDER BY log_date DESC" );
    ?>
    <div class="wrap">

      <h1>Usage</h1>


        <div style="margin-bottom: 23px;">
            <p style="margin-top:10px; font-size: 20px; color: darkgreen;">
                <strong></strong> On the front-end of your site, simply highlight any text. An audio panel will appear near your selection. Click the play button to hear the selected text spoken aloud.
            </p>
        </div>


      <h1>Screenshot of a Front-end Page:</h1>

        <?php 
    $image_file = 'assets/screenshot-1.png';
    if ( function_exists( 'sst_fs' ) ) {
    }
    $image_url = plugin_dir_url( __FILE__ ) . $image_file;
    ?>

        <div style="margin-bottom: 23px;">
            <img src="<?php 
    echo esc_url( $image_url );
    ?>" alt="Demo of plugin" style="max-width:50%; height:auto; border: 4px solid #ccc;">
        </div>


      <h1>Speech TTS Daily Usage</h1>
      <table class="widefat striped" style="max-width:500px">
        <thead><tr><th>Date</th><th>Plays</th><th>Restarts</th></tr></thead>
        <tbody>
        <?php 
    if ( $rows ) {
        foreach ( $rows as $r ) {
            printf(
                '<tr><td>%s</td><td>%d</td><td>%d</td></tr>',
                esc_html( $r->log_date ),
                intval( $r->plays ),
                intval( $r->restarts )
            );
        }
    } else {
        echo '<tr><td colspan="3">No data yet.</td></tr>';
    }
    ?>
        </tbody>

<tfoot>
  <tr>
    <th><?php esc_html_e( 'Total', 'selection-speech-tts' ); ?></th>
    <th><?php echo esc_html( $total_plays ); ?></th>
    <th><?php echo esc_html( $total_restarts ); ?></th>
  </tr>
</tfoot>


      </table>

      <form method="post" action="<?php 
    echo esc_url( admin_url( 'admin-post.php' ) );
    ?>">
        <?php 
    wp_nonce_field( 'sstts_download' );
    ?>
        <input type="hidden" name="action" value="sstts_download">
        <button class="button button-primary">Download CSV</button>
      </form>

<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>"
      onsubmit="return confirm('Are you sure you want to clear the table? This action cannot be undone.');"
      style="margin-top:12px">
    <?php wp_nonce_field( 'sstts_clear' ); ?>
    <input type="hidden" name="action" value="sstts_clear_table">
    <button class="button"><?php esc_html_e( 'Clear Table', 'selection-speech-tts' ); ?></button>
</form>


    </div>
    <?php 
}

/**
 * REST API endpoint for tracking
 */
add_action( 'rest_api_init', function () {
    register_rest_route( 'sstts/v1', '/hit', array(
        'methods'             => 'POST',
        'callback'            => 'sstts_rest_hit',
        // Intentionally public – only logs aggregated counters, no PII.
        'permission_callback' => '__return_true',
        'args'                => array(
            'type' => array(
                'required'          => true,
                'sanitize_callback' => function( $value ) {
                    $v = is_string( $value ) ? strtolower( $value ) : '';
                    return in_array( $v, array( 'play', 'restart' ), true ) ? $v : '';
                },
                'validate_callback' => function( $value ) {
                    return in_array( strtolower( (string) $value ), array( 'play', 'restart' ), true );
                },
            ),
        ),
        'show_in_index'       => false,
    ) );
} );

function sstts_rest_hit( WP_REST_Request $req ) {
    global $wpdb;

    // Accept both form-data and JSON safely
    $type = $req->get_param('type');
    if ( empty( $type ) ) {
        $json = $req->get_json_params();
        if ( is_array( $json ) && ! empty( $json['type'] ) ) {
            $type = $json['type'];
        }
    }
    $type = is_string( $type ) ? strtolower( $type ) : '';

    if ( ! in_array( $type, array( 'play', 'restart' ), true ) ) {
        return new WP_REST_Response( array( 'error' => 'bad type' ), 400 );
    }

    // No IPs, no user IDs, no user agents – keep it anonymous
    $table = $wpdb->prefix . 'sstts_usage';
    $today = gmdate( 'Y-m-d' );

$exists = ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $table ) ) === $table );
if ( ! $exists ) {
    return new WP_REST_Response( array( 'error' => 'storage not ready' ), 503 );
}

    // Upsert row for today
    $row = $wpdb->get_row( $wpdb->prepare(
        "SELECT * FROM `{$table}` WHERE `log_date` = %s",
        $today
    ) );

    if ( $row ) {
        if ( 'play' === $type ) {
            $wpdb->query( $wpdb->prepare(
                "UPDATE `{$table}` SET `plays` = `plays` + 1 WHERE `log_date` = %s",
                $today
            ) );
        } else {
            $wpdb->query( $wpdb->prepare(
                "UPDATE `{$table}` SET `restarts` = `restarts` + 1 WHERE `log_date` = %s",
                $today
            ) );
        }
    } else {
        $wpdb->insert(
            $table,
            array(
                'log_date' => $today,
                'plays'    => ( 'play' === $type ) ? 1 : 0,
                'restarts' => ( 'restart' === $type ) ? 1 : 0,
            ),
            array( '%s', '%d', '%d' )
        );
    }

    // Maintain a global total via options
    $option_key = ( 'play' === $type ) ? 'sstts_total_plays' : 'sstts_total_restarts';
    update_option( $option_key, (int) get_option( $option_key, 0 ) + 1 );

    return rest_ensure_response( array( 'logged' => true ) );
}

