<?php
/**
 * FajaedeSEO Mollie Payment Gateway
 *
 * @package FajaedeSEO
 */

defined( 'ABSPATH' ) || exit;

if ( ! class_exists( 'FajaedeSEO_Mollie_Gateway' ) ) {

    /**
     * Implements the payment gateway for Mollie.
     */
    class FajaedeSEO_Mollie_Gateway implements \FajaedeSEO_Payment_Gateway_Interface {
        
        /**
         * @var mixed|null
         */
        private $api_client = null;

        public function get_id() : string {
            return 'mollie';
        }

        public function get_name() : string {
            return 'Mollie';
        }

        public function init() : void {
            // Initialiseer de Mollie API Client
            try {
                $api_key = get_option( 'fajaedeseo_mollie_api_key' );
                if ( ! empty( $api_key ) && class_exists( '\Mollie\Api\MollieApiClient' ) ) {
                    $mollie_class = '\Mollie\Api\MollieApiClient';
                    $this->api_client = new $mollie_class();
                    $this->api_client->setApiKey( $api_key );
                }
            } catch ( \Exception $e ) {
                // Log de fout als de SDK niet geladen kan worden.
                // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Intentional error logging for gateway issues.
                error_log( 'FajaedeSEO Mollie Init Error: ' . $e->getMessage() );
            }
        }

        public function process_checkout( \WP_REST_Request $request ) {
            $params        = $request->get_params();
            $email         = sanitize_email( $params['customer_email'] ?? '' );
            $email_confirm = sanitize_email( $params['customer_email_confirm'] ?? '' );
            $name          = sanitize_text_field( $params['customer_name'] ?? '' );
            $plan          = sanitize_text_field( $params['plan_tier'] ?? 'pro' );
            $country_code  = sanitize_text_field( $params['country_code'] ?? 'BE' ); // Default to Belgium
            $customer_type = sanitize_text_field( $params['customer_type'] ?? 'particulier' ); // 'particulier' or 'onderneming'
            $vat_number    = sanitize_text_field( $params['vat_number'] ?? '' ); // For B2B customers
            $referer       = wp_get_referer() ?: home_url( '/checkout/' );

            if ( ! $this->api_client ) {
                wp_safe_redirect( add_query_arg( 'error', 'gateway_not_configured', $referer ) );
                exit;
            }
            
            // Server-side check: Zorg dat het e-mailadres altijd is ingevuld en overeenkomt
            if ( empty( $email ) || $email !== $email_confirm ) {
                wp_safe_redirect( add_query_arg( 'error', 'email_mismatch', $referer ) );
                exit;
            }

            // Antifraude: Controleer of het IP-adres (EU) overeenkomt met de landkeuze (Non-EU) om BTW-ontwijking te voorkomen.
            $ip = function_exists('fajaedeseo_get_client_ip') ? fajaedeseo_get_client_ip() : '';

            if ( ! empty( $ip ) && ! in_array( $ip, ['127.0.0.1', '::1'] ) ) {
                // Gebruik een timeout van 3 sec zodat we de checkout niet vertragen als de API traag is.
                $response = wp_remote_get( "http://ip-api.com/json/{$ip}?fields=status,countryCode", ['timeout' => 3] );
                if ( ! is_wp_error( $response ) ) {
                    $geo_data = json_decode( wp_remote_retrieve_body( $response ), true );
                    if ( isset( $geo_data['status'], $geo_data['countryCode'] ) && $geo_data['status'] === 'success' ) {
                        $ip_country = $geo_data['countryCode'];
                        // Blokkeer als het IP in de EU is, maar de klant een exportland (0% BTW) selecteert.
                        if ( ! \FajaedeSEO_VAT_Calculator::is_eu_country( $country_code ) && \FajaedeSEO_VAT_Calculator::is_eu_country( $ip_country ) ) {
                            wp_safe_redirect( add_query_arg( 'error', urlencode( 'Veiligheidscontrole: Uw netwerklocatie bevindt zich in de EU (' . $ip_country . '). Het is niet toegestaan een Non-EU land te selecteren.' ), $referer ) );
                            exit;
                        }
                    }
                }
            }

            $prices = [
                'pro'     => '79.00',
                'premium' => '149.00',
                'agency'  => '499.00',
            ];
            $price_excl_vat = (float) ( $prices[ $plan ] ?? $prices['pro'] );
            $order_id = 'FSEO-' . time() . '-' . wp_generate_password( 6, false );

            try {
                // Calculate VAT
                $is_b2b_with_vat_id = ($customer_type === 'onderneming') && !empty($vat_number) && \FajaedeSEO_VAT_Calculator::validate_eu_vat_number($vat_number);
                $vat_info = \FajaedeSEO_VAT_Calculator::calculate($price_excl_vat, $country_code, $is_b2b_with_vat_id);

                // The final amount to send to Mollie (incl. VAT)
                $final_amount = (string) number_format($vat_info['price_incl_vat'], 2, '.', '');

                // 1. Maak eerst een klant aan in Mollie
                $customer = $this->api_client->customers->create([
                    'name'  => $name,
                    'email' => $email,
                ]);

                // 2. Start een eenmalige betaling (100% veilig, geen SEPA of storneringsrisico)
                $payment  = $this->api_client->payments->create(
                    [
						'amount'      => [
							'currency' => 'EUR',
							'value'    => $final_amount, // Amount incl. VAT
						],
                        'customerId'   => $customer->id,
                        'description'  => 'FajaedeSEO ' . ucfirst( $plan ) . ' License (' . $order_id . ')',
                        'redirectUrl'  => home_url( '/checkout/success/?order=' . $order_id ),
                        'webhookUrl'   => get_rest_url( null, 'fajaedeseo/v1/webhook/mollie' ),
                        'metadata'     => [
                            'order_id'      => $order_id,
                            'plan_tier'     => $plan,
                            'email'         => $email,
                            'amount'        => $final_amount, // Final amount incl. VAT
                            'country_code'  => strtoupper($country_code),
                            'customer_type' => $customer_type,
                            'vat_number'    => $vat_number,
                            'vat_rate'      => $vat_info['vat_rate'],
                            'vat_amount'    => $vat_info['vat_amount'],
                            'price_excl_vat' => $price_excl_vat,
                            'is_reverse_charge' => $is_b2b_with_vat_id ? '1' : '0',
                            'is_export'     => $vat_info['is_export'] ? '1' : '0',
						],
                    ]
                );

                // Redirect naar Mollie checkout.
                // phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect -- Redirects to external Mollie payment page.
                wp_redirect( $payment->getCheckoutUrl(), 303 );
                exit;

            } catch ( \Exception $e ) {
                wp_safe_redirect( add_query_arg( 'error', urlencode( $e->getMessage() ), $referer ) );
                exit;
            }
        }

        public function handle_webhook( \WP_REST_Request $request ) {
            if ( ! $this->api_client ) {
                return new \WP_REST_Response( 'Gateway not configured', 500 );
            }

            try {
                $payment_id = $request->get_param( 'id' );
                if ( empty( $payment_id ) ) {
                    return new \WP_REST_Response( 'Missing payment ID', 400 );
                }

                $payment = $this->api_client->payments->get( $payment_id );

                if ( $payment->isPaid() && ! $payment->hasRefunds() && ! $payment->hasChargebacks() ) {
                    // Betaling is succesvol.
                    $metadata = (array) $payment->metadata;

                    // Bij een automatische verlenging missen we mogelijk de originele metadata.
                    // We halen deze op uit het Mollie Abonnement als fallback.
                    if ( $payment->sequenceType === 'recurring' && $payment->subscriptionId && $payment->customerId ) {
                        try {
                            $subscription = $this->api_client->subscriptions->getForId($payment->customerId, $payment->subscriptionId);
                            if ( $subscription && $subscription->metadata ) {
                                $metadata = array_merge($metadata, (array) $subscription->metadata);
                            }
                        } catch (\Exception $e) {}
                    }

                    // Hardening: Sanitize all data received from the webhook before processing.
                    $plan           = sanitize_key($metadata['plan_tier'] ?? 'pro');
                    $email          = sanitize_email($metadata['email'] ?? '');
                    $order_id       = sanitize_text_field($metadata['order_id'] ?? $payment->id);
                    $amount         = sanitize_text_field($metadata['amount'] ?? $payment->amount->value);
                    $country_code   = sanitize_text_field($metadata['country_code'] ?? 'BE');
                    $customer_type  = sanitize_key($metadata['customer_type'] ?? 'particulier');
                    $vat_number     = sanitize_text_field($metadata['vat_number'] ?? '');
                    $vat_rate       = floatval($metadata['vat_rate'] ?? 0);
                    $vat_amount     = floatval($metadata['vat_amount'] ?? 0);
                    $is_reverse_charge = ($metadata['is_reverse_charge'] ?? '0') === '1';
                    $is_export      = ($metadata['is_export'] ?? '0') === '1';

                    if (empty($email)) {
                        error_log('Mollie Webhook Error: Email is missing from metadata for payment ' . $payment->id); // phpcs:ignore
                        return new \WP_REST_Response( 'Email missing from metadata', 400 );
                    }

                    // 1. Is dit de allereerste betaling? Maak direct een abonnement aan in Mollie!
                    if ( $payment->sequenceType === 'first' && $payment->customerId ) {
                        // Dit zet het huidige bedrag voor ALTIJD vast in het Mollie dashboard (Introductieprijs Garantie!)
                        try {
                            $this->api_client->subscriptions->createForId($payment->customerId, [
                                'amount'      => [
                                    'currency' => 'EUR',
                                    'value'    => number_format((float)$amount, 2, '.', ''),
                                ],
                                'interval'    => '12 months',
                                'description' => 'FajaedeSEO ' . ucfirst($plan) . ' License Renewal',
                                'webhookUrl'  => get_rest_url( null, 'fajaedeseo/v1/webhook/mollie' ),
                                'metadata'    => $metadata
                            ]);
                        } catch (\Exception $e) {
                            error_log('Mollie Subscription Error: ' . $e->getMessage()); // phpcs:ignore
                        }
                    }

                    // 2. Licentie aanmaken of verlengen
                    $license_class = '\FajaedeSEO_Pro_License';
                    if ( class_exists( $license_class ) ) {
                        if ( $payment->sequenceType === 'recurring' ) {
                            // Automatische verlenging na een jaar (zoek licentie en verleng)
                            global $wpdb;
                            $user = get_user_by('email', $email);
                            
                            $license = false;
                            if ($user) {
                                $cache_key = 'fajaedeseo_user_license_' . $user->ID . '_' . $plan;
                                $license = wp_cache_get($cache_key, 'fajaedeseo');
                                if (false === $license) {
                                    $license = $wpdb->get_row($wpdb->prepare("SELECT id FROM `" . esc_sql($wpdb->prefix . 'fajaedeseo_licenses') . "` WHERE user_id = %d AND plan_level = %s ORDER BY id DESC LIMIT 1", $user->ID, $plan)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
                                    wp_cache_set($cache_key, $license, 'fajaedeseo', 5 * MINUTE_IN_SECONDS);
                                }

                                if ($license) {
                                    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                                    $wpdb->update($wpdb->prefix . 'fajaedeseo_licenses', ['expires_at' => gmdate('Y-m-d H:i:s', strtotime('+366 days'))], ['id' => $license->id]);
                                    wp_cache_delete($cache_key, 'fajaedeseo');
                                }
                            }
                        } elseif ( method_exists( $license_class, 'generate_and_provision_license' ) ) {
                            // Eerste betaling: Maak account aan en genereer de nieuwe sleutel
                            // Pass VAT information to license generation
                            $result = $license_class::generate_and_provision_license( 
                                $email, 
                                $plan, 
                                $payment->id, 
                                $order_id, 
                                (float) $payment->amount->value, 
                                'EUR',
                                [
                                    'country_code' => $country_code,
                                    'customer_type' => $customer_type,
                                    'vat_number' => $vat_number,
                                    'vat_rate' => $vat_rate,
                                    'vat_amount' => $vat_amount,
                                    'is_reverse_charge' => $is_reverse_charge,
                                    'is_export' => $is_export,
                                ]
                            );
                            if ( isset( $result['success'] ) && $result['success'] ) {
                                $license_class::send_license_email( $email, $plan, $result['license_key'], $result['plain_password'], $result['license_id'] ?? 0 );
                            } else {
                                // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
                                error_log('FajaedeSEO License Generation Failed: ' . ($result['message'] ?? 'Unknown error'));
                            }
                        }
                    }
                }

                return new \WP_REST_Response( 'OK', 200 );

            } catch ( \Exception $e ) {
                error_log('Mollie Webhook Error: ' . $e->getMessage()); // phpcs:ignore
                return new \WP_REST_Response( 'API Error: ' . $e->getMessage(), 500 );
            }
        }

        public function render_settings_fields() : void {
            $api_key = get_option( 'fajaedeseo_mollie_api_key', '' );
            ?>
            <tr valign="top">
                <th scope="row"><label for="fajaedeseo_mollie_api_key"><?php echo esc_html__( 'Mollie API Key', 'fajaedeseo-ai' ); ?></label></th>
                <td>
                    <input type="password" id="fajaedeseo_mollie_api_key" name="fajaedeseo_mollie_api_key" value="<?php echo esc_attr( $api_key ); ?>" class="regular-text" placeholder="live_..." />
                    <p class="description">
                        <?php esc_html_e( 'Enter your live Mollie API key.', 'fajaedeseo-ai' ); ?>
                    </p>
                </td>
            </tr>
            <?php
        }
    }
}