<?php
namespace Xxxwraithxxx\PayraCashCryptoPayment;

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

class Transaction extends Constants
{

    public function register()
    {
        add_action('admin_init', [$this, 'payracacr_action_generate_reports_files']);
    }

    public function payracacr_action_generate_reports_files()
    {
        if (!isset($_GET['page']) || $_GET['page'] !== 'payracacr-page-settings') {
            return;
        }

        if (!current_user_can('manage_options')) {
            wp_die(esc_html__('Unauthorized', 'payra-cash-crypto-payment'));
        }

        if (isset($_GET['payra_csv']) || isset($_GET['payra_print'])) {

            if (ob_get_length()) ob_clean();

            if (!isset($_GET['_wpnonce']) || !wp_verify_nonce(
                    sanitize_text_field(wp_unslash($_GET['_wpnonce'])),
                    'payra_transactions_filters'
                )
            ) {
                wp_die(esc_html__('Invalid nonce', 'payra-cash-crypto-payment'));
            }

            // get filters from $_GET
            $filters = [
                'transactions_search'   => isset($_GET['transactions_search']) ? sanitize_text_field(wp_unslash($_GET['transactions_search'])) : '',
                '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'])) : '',
                'price_min'             => isset($_GET['price_min']) ? sanitize_text_field(wp_unslash($_GET['price_min'])) : '',
                'price_max'             => isset($_GET['price_max']) ? sanitize_text_field(wp_unslash($_GET['price_max'])) : '',
                'status_filter'         => isset($_GET['status_filter']) ? sanitize_text_field(wp_unslash($_GET['status_filter'])) : '',
            ];
        
            if (isset($_GET['payra_print'])) {
                // Limit to 1000 for performance
                $report_data = $this->get_transactions(1000, 1, $filters);
                $total_found = $this->get_total_count($filters);
                $total_price = 0; 
                $total_fee = 0;

                ?>

                <!DOCTYPE html>
                <html lang="pl">
                <head>
                    <meta charset="UTF-8">
                    <title><?php echo esc_html('PayraCash - Report', 'payra-cash-crypto-payment')?></title>
                    <style>
                        body { font-family: "Segoe UI", Tahoma, sans-serif; padding: 40px; line-height: 1.6; }
                        table { width: 100%; border-collapse: collapse; margin-top: 20px; }
                        th, td { border: 1px solid #eee; padding: 12px; text-align: left; }
                        th { background-color: #f8f9fa; color: #333; text-transform: uppercase; font-size: 11px; }
                        tr:nth-child(even) { background-color: #fafafa; }
                        .report-header { display: flex; justify-content: space-between; align-items: center; border-bottom: 2px solid #333; padding-bottom: 10px; }
                        .logo { font-size: 24px; font-weight: bold; color: #0073aa; }
                        @media print {
                            .no-print { display: none; }
                            body { padding: 0; }
                        }
                    </style>
                </head>
                <body onload="window.print()">
                    <div class="report-header">
                        <div class="logo">
                            <img src="<?php echo esc_url(plugins_url('assets/img/payracash-logo.png', PAYRACACR_CASH_PLUGIN_FILE)); ?>" width="24" height="24" alt="Payra Cash logo"/>
                            <span style="color:#364CCD">Payra Cash</span>
                        </div>
                        <div>Generated: <?php echo esc_html(gmdate('Y-m-d H:i')); ?></div>
                    </div>

                    <div class="limit-info">
                        <?php if ($total_found > 1000): ?>
                            <strong>Note:</strong> Found <?php echo intval($total_found); ?> transactions. Only the first 1000 are shown below. Please use filters to narrow down your search.
                        <?php else: ?>
                            Showing all <?php echo intval($total_found); ?> matching transactions.
                        <?php endif; ?>
                    </div>

                    <table>
                        <thead>
                            <tr>
                                <th>Order ID</th>
                                <th>Status</th>
                                <th>Date</th>
                                <th>Price</th>
                                <th>Fee</th>
                                <th>Token</th>
                                <th>Network</th>
                                <th>Sender</th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php if (empty($report_data)): ?>
                                <tr>
                                    <td colspan="7" style="text-align:center;">No transactions found for selected filters.</td>
                                </tr>
                            <?php else: ?>
                                <?php foreach ($report_data as $row):
                                    $price = floatval($row['price']);
                                    $fee = floatval($row['fee_in_wei'] / 1_000_000);
                                    $total_price += $price;
                                    $total_fee += $fee; 
                                ?>
                                <tr>
                                    <td><b><?php echo esc_html($row['order_prefix_id']); ?></b></td>
                                    <td><?php echo esc_html($row['status_name']); ?></td>
                                    <td><?php echo esc_html($row['created_at']); ?></td>
                                    <td>$<?php echo number_format($price, 2); ?></td>
                                    <td>$<?php echo number_format($fee, 4); ?></td>
                                    <td><?php echo esc_html($row['currency_symbol']); ?></td>
                                    <td><?php echo esc_html($row['network_label']); ?></td>
                                    <td style="font-family:monospace; font-size:14px;">
                                        <?php if (!empty($row['sender'])) {
                                            echo esc_html(Helper::shorten_hash($row['sender']));
                                        } else { 
                                            echo esc_html('...', 'payra-cash-crypto-payment');
                                        } ?>
                                    </td>
                                </tr>
                                <?php endforeach; ?>
                            <?php endif; ?>
                        </tbody>
                        <?php if (!empty($report_data)): ?>
                        <tfoot>
                            <tr>
                                <td colspan="3" style="text-align: right;">TOTAL SUMMARY:</td>
                                <td>$<?php echo number_format($total_price, 2); ?></td>
                                <td>$<?php echo number_format($total_fee, 4); ?></td>
                                <td colspan="3"></td>
                            </tr>
                        </tfoot>
                        <?php endif; ?>
                    </table>
                    <div style="margin-top: 30px;" class="no-print">
                        <button onclick="window.close()" style="padding: 10px 20px; cursor: pointer;">
                            <?php echo esc_html('Close and return to Dashboard', 'payra-cash-crypto-payment'); ?>
                        </button>
                    </div>
                </body>
                </html>
                <?php
                exit;
            }
  
            if (isset($_GET['payra_csv'])) {
                $report_data = $this->get_transactions(1000, 1, $filters);
                $total_found = $this->get_total_count($filters);
                $filename = sanitize_file_name('payracash-report-' . gmdate('Y-m-d') . '.csv');

                header('Content-Type: text/csv; charset=utf-8');
                header('Content-Disposition: attachment; filename=' . $filename);
                
                // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fopen
                $output = fopen('php://output', 'w');
                fprintf($output, chr(0xEF).chr(0xBB).chr(0xBF));
                fputcsv($output, ['Order ID', 'Status', 'Date', 'Price', 'Fee', 'Token', 'Network', 'Sender']);

                $total_price = 0;
                $total_fee = 0;

                if (!empty($report_data)) {
                    foreach ($report_data as $row) {
                        $price = floatval($row['price']);
                        $fee = floatval($row['fee_in_wei'] / 1_000_000);
                        $total_price += $price;
                        $total_fee += $fee;

                        fputcsv($output, [
                            $row['order_prefix_id'],
                            $row['status_name'],
                            $row['created_at'],
                            '$' . $price,
                            '$' . number_format($fee, 4, '.', ''),
                            $row['currency_symbol'],
                            $row['network_label'],
                            Helper::shorten_hash($row['sender'])
                        ]);
                    }

                    // Add emoty row
                    fputcsv($output, []);

                    // Summary
                    fputcsv($output, [
                        'TOTAL SUMMARY', // Row: Order ID
                        '',              // Row: Status
                        '',              // Row: Date
                        '$' . number_format($total_price, 2, '.', ''), // Row: Price
                        '$' . number_format($total_fee, 2, '.', ''),   // Row: Fee
                        '',              // Row: Currency
                        '',              // Row: Network
                        ''               // Row: Sender
                    ]);
                }

                if ($total_found > 1000) {
                    fputcsv($output, []);
                    fputcsv($output, ['ATTENTION:', 'Only first 1000 of ' . $total_found . ' transactions exported. Use filters for more.']);
                }
                
                // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose
                fclose($output);
                exit;
            }
        }  
    }

    public function get_transactions($per_page = 50, $paged = 1, $filters = [])
    {
        global $wpdb;

        // Build WHERE
        $conditions = $this->prepare_filter_conditions($filters);
        $where_sql = $conditions['where'];
        $params = $conditions['params'];
        $offset = (max(1, (int)$paged) - 1) * (int)$per_page;
        
        // Add limit to params
        $params[] = $per_page;
        $params[] = $offset;

        $transactions_table = Constants::get_table('transactions');
        $transaction_statuses_table = Constants::get_table('transaction_statuses');
        $networks_table = Constants::get_table('networks');

        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
        return $wpdb->get_results(
            $wpdb->prepare("
                SELECT
                    t.*, 
                    s.name AS status_name, 
                    s.description AS status_description, 
                    n.label AS network_label, 
                    n.block_explorer_url 
                FROM {$transactions_table} t
                LEFT JOIN {$transaction_statuses_table} s 
                    ON t.status_id = s.id
                LEFT JOIN {$networks_table} n 
                    ON t.network_id = n.id
                WHERE $where_sql
                ORDER BY t.created_at DESC
                LIMIT %d OFFSET %d", 
                $params
            ), 
            ARRAY_A
        );
    }

    /**
     * Count all filter transactions for pagination
     */
    public function get_total_count($filters = [])
    {
        global $wpdb;

        $conditions = $this->prepare_filter_conditions($filters);
        $where_sql = $conditions['where'];
        $params = $conditions['params'];

        $transactions_table = Constants::get_table('transactions');
        $transaction_statuses_table = Constants::get_table('transaction_statuses');

        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
        if (empty($params)) {
            return (int) $wpdb->get_var("
                SELECT COUNT(*) 
                FROM {$transactions_table} t 
                LEFT JOIN {$transaction_statuses_table} s 
                    ON t.status_id = s.id
                WHERE {$where_sql}"
            );
        }

        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
        return (int) $wpdb->get_var(
            $wpdb->prepare("
                SELECT COUNT(*) 
                FROM {$transactions_table} t 
                LEFT JOIN {$transaction_statuses_table} s 
                    ON t.status_id = s.id
                WHERE {$where_sql}",
                $params
            )
        );
    }

    /**
     * Builds safe SQL WHERE clause using prepared placeholders only.
     * @return array{where:string, params:array}
     */
    private function prepare_filter_conditions($filters)
    {
        global $wpdb;

        $where = ['1=1'];
        $params = [];

        // 1. General search (Order ID, Hash, Payer)
        if (!empty($filters['transactions_search'])) {
            $like = '%' . $wpdb->esc_like(trim($filters['transactions_search'])) . '%';
            $where[] = "(t.order_prefix_id LIKE %s OR t.tx_hash LIKE %s OR t.sender LIKE %s OR s.name LIKE %s)";
            $params[] = $like; $params[] = $like; $params[] = $like; $params[] = $like;
        }

        // 2. Date
        if (!empty($filters['date_from'])) {
            $where[] = "t.created_at >= %s";
            $params[] = $filters['date_from'] . ' 00:00:00';
        }
        if (!empty($filters['date_to'])) {
            $where[] = "t.created_at <= %s";
            $params[] = $filters['date_to'] . ' 23:59:59';
        }

        // 3. Price
        if (!empty($filters['price_min'])) {
            $where[] = "t.price >= %f";
            $params[] = floatval($filters['price_min']);
        }
        if (!empty($filters['price_max'])) {
            $where[] = "t.price <= %f";
            $params[] = floatval($filters['price_max']);
        }

        // 4. Status
        if (!empty($filters['status_filter'])) {
            $where[] = "s.name = %s";
            $params[] = sanitize_text_field($filters['status_filter']);
        }

        return [
            'where'  => implode(' AND ', $where),
            'params' => $params
        ];
    }

}
