<?php

namespace WPVOID\StockBeacon;

use WPVOID\StockBeacon\Admin\AdminPage;
use WPVOID\StockBeacon\Admin\ProductColumn;
use WPVOID\StockBeacon\Admin\ProductTab;
use WPVOID\StockBeacon\Api\SettingsEndpoints;
use WPVOID\StockBeacon\Api\WaitlistEndpoints;
use WPVOID\StockBeacon\Core\CsvSanitizer;
use WPVOID\StockBeacon\Core\Throttle;
use WPVOID\StockBeacon\Core\WaitlistManager;
use WPVOID\StockBeacon\Frontend\FormRenderer;
use WPVOID\StockBeacon\Integrations\GDPRHandler;
use WPVOID\StockBeacon\Integrations\WooCommerceHooks;
use WPVOID\StockBeacon\Notifications\EmailManager;
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
class Plugin {
    public function run() : void {
        $this->load_files();
        Activator::maybe_upgrade();
        $manager = new WaitlistManager();
        $throttle = new Throttle();
        $form = new FormRenderer($manager);
        $email = new EmailManager($manager);
        $optin_service = null;
        ( new WooCommerceHooks(
            $manager,
            $throttle,
            $form,
            $email,
            $optin_service
        ) )->register();
        ( new ProductColumn($manager) )->register();
        ( new ProductTab() )->register();
        ( new AdminPage() )->register();
        ( new GDPRHandler($manager) )->register();
        ( new SettingsEndpoints($email) )->register();
        ( new WaitlistEndpoints($manager) )->register();
        // CSV export is available on all plans.
        add_action( 'wp_ajax_stockbeacon_export_csv', static function () use($manager) {
            check_ajax_referer( 'stockbeacon_export_csv', 'nonce' );
            if ( !current_user_can( 'manage_woocommerce' ) ) {
                wp_die( esc_html__( 'Forbidden.', 'stockbeacon-product-waitlists-for-woocommerce' ), '', array(
                    'response' => 403,
                ) );
            }
            $product_id = ( isset( $_GET['product_id'] ) ? absint( wp_unslash( $_GET['product_id'] ) ) : 0 );
            $status = ( isset( $_GET['status'] ) ? sanitize_key( wp_unslash( $_GET['status'] ) ) : '' );
            $date_from = ( isset( $_GET['date_from'] ) ? sanitize_text_field( wp_unslash( $_GET['date_from'] ) ) : '' );
            $date_to = ( isset( $_GET['date_to'] ) ? sanitize_text_field( wp_unslash( $_GET['date_to'] ) ) : '' );
            $status = ( in_array( $status, array(
                'active',
                'pending',
                'notified',
                'purchased',
                'unsubscribed'
            ), true ) ? $status : '' );
            $date_from = ( preg_match( '/^\\d{4}-\\d{2}-\\d{2}$/', $date_from ) ? $date_from : '' );
            $date_to = ( preg_match( '/^\\d{4}-\\d{2}-\\d{2}$/', $date_to ) ? $date_to : '' );
            $has_filter = '' !== $status || '' !== $date_from || '' !== $date_to;
            // Use Pro CsvExporter when available, fall back to inline generation.
            if ( !$has_filter && class_exists( '\\WPVOID\\StockBeacon\\Analytics\\CsvExporter' ) ) {
                $csv_string = ( new \WPVOID\StockBeacon\Analytics\CsvExporter($manager) )->get_csv_string( $product_id );
            } else {
                global $wpdb;
                $table = esc_sql( $wpdb->prefix . 'stockbeacon_subscriptions' );
                $posts_table = esc_sql( $wpdb->posts );
                $users_table = esc_sql( $wpdb->users );
                // Seed with a constant condition so every query runs through $wpdb->prepare() with at least one placeholder.
                $where = array('1=%d');
                $params = array(1);
                if ( $product_id > 0 ) {
                    $where[] = 's.product_id=%d';
                    $params[] = $product_id;
                }
                if ( '' !== $status ) {
                    $where[] = 's.status=%s';
                    $params[] = $status;
                }
                if ( '' !== $date_from ) {
                    $where[] = 's.created_at >= %s';
                    $params[] = $date_from . ' 00:00:00';
                }
                if ( '' !== $date_to ) {
                    $where[] = 's.created_at <= %s';
                    $params[] = $date_to . ' 23:59:59';
                }
                $where_sql = ' WHERE ' . implode( ' AND ', $where );
                $base_sql = 'SELECT s.*, COALESCE(CASE WHEN p.post_type=\'product_variation\' AND par.post_title IS NOT NULL THEN par.post_title ELSE p.post_title END, \'\') AS product_name FROM ' . $table . ' s LEFT JOIN ' . $posts_table . ' p ON p.ID=s.product_id LEFT JOIN ' . $posts_table . ' par ON par.ID=p.post_parent AND p.post_type=\'product_variation\'';
                // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Fully prepared; only esc_sql()'d plugin/core table names are interpolated, placeholders live in the concatenated WHERE fragments.
                $sql = $wpdb->prepare( $base_sql . $where_sql . ' ORDER BY s.id DESC', ...$params );
                $headers = array(
                    'ID',
                    'Product ID',
                    'Product Name',
                    'Variation ID',
                    'Email',
                    'WP User ID',
                    'Customer Edit URL',
                    'Status',
                    'Product Stock Status',
                    'Signed Up',
                    'Last Email Sent',
                    'Purchased At'
                );
                $rows = array($headers);
                // Collect unique emails for bulk user lookup.
                // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Fully prepared above; %s placeholders generated to match the email list, uncached admin export read on plugin/core tables.
                $raw_rows = (array) $wpdb->get_results( $sql );
                $all_emails = array_unique( array_column( $raw_rows, 'email' ) );
                $user_map = array();
                if ( !empty( $all_emails ) ) {
                    $placeholders = implode( ',', array_fill( 0, count( $all_emails ), '%s' ) );
                    $user_rows = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT ID, user_email FROM ' . $users_table . ' WHERE user_email IN (' . $placeholders . ')', ...$all_emails ) );
                    foreach ( $user_rows as $u ) {
                        $user_map[strtolower( (string) $u->user_email )] = (int) $u->ID;
                    }
                }
                // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, PluginCheck.Security.DirectDB.UnescapedDBParameter
                foreach ( $raw_rows as $row ) {
                    $uid = $user_map[strtolower( (string) $row->email )] ?? 0;
                    $edit_url = ( $uid > 0 ? ( get_edit_user_link( $uid ) ?: '' ) : '' );
                    $stock_status = (string) get_post_meta( (int) $row->product_id, '_stock_status', true );
                    $rows[] = array(
                        (string) $row->id,
                        (string) $row->product_id,
                        (string) ($row->product_name ?? ''),
                        (string) $row->variation_id,
                        (string) $row->email,
                        ( $uid > 0 ? (string) $uid : '' ),
                        $edit_url,
                        (string) $row->status,
                        $stock_status,
                        (string) $row->created_at,
                        (string) ($row->notified_at ?? ''),
                        (string) ($row->purchased_at ?? '')
                    );
                }
                $lines = array();
                foreach ( $rows as $fields ) {
                    $escaped = array_map( array(CsvSanitizer::class, 'escape_cell'), $fields );
                    $lines[] = implode( ',', $escaped );
                }
                $csv_string = implode( "\n", $lines ) . "\n";
            }
            $name = ( $product_id > 0 ? 'stockbeacon-product-' . $product_id . '.csv' : 'stockbeacon-all.csv' );
            nocache_headers();
            header( 'Content-Type: text/csv; charset=utf-8' );
            header( 'Content-Disposition: attachment; filename="' . $name . '"' );
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSV file download, not HTML; every cell is sanitized via CsvSanitizer::escape_cell() (RFC 4180 quoting + formula-injection neutralization).
            echo $csv_string;
            exit;
        } );
    }

    private function load_files() : void {
        $files = array(
            'includes/core/class-csv-sanitizer.php',
            'includes/core/class-subscription.php',
            'includes/core/class-signup-validator.php',
            'includes/core/class-waitlist-manager.php',
            'includes/core/class-throttle.php',
            'includes/notifications/class-email-manager.php',
            'includes/notifications/class-restock-notifier.php',
            'includes/integrations/class-woocommerce-hooks.php',
            'includes/integrations/class-gdpr-handler.php',
            'includes/frontend/class-form-renderer.php',
            'includes/admin/class-admin-bundle.php',
            'includes/admin/class-admin-page.php',
            'includes/admin/class-product-column.php',
            'includes/admin/class-product-tab.php',
            'includes/api/class-rest-controller.php',
            'includes/api/class-waitlist-endpoints.php',
            'includes/api/class-settings-endpoints.php'
        );
        foreach ( $files as $file ) {
            $path = STOCKBEACON_PATH . $file;
            if ( file_exists( $path ) ) {
                require_once $path;
            }
        }
    }

}
