<?php
/**
 * Core AJAX Handler.
 * Integrates with Pexally Central API for bulk queuing and limits.
 */

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

class PexEmail_Ajax {

    public function init() {
        add_action( 'wp_ajax_pexemail_create_list', [ $this, 'create_list' ] );
        add_action( 'wp_ajax_pexemail_delete_list', [ $this, 'delete_list' ] );
        add_action( 'wp_ajax_pexemail_edit_list', [ $this, 'edit_list' ] );

        add_action( 'wp_ajax_pexemail_add_single_contact', [ $this, 'add_single_contact' ] );
        add_action( 'wp_ajax_pexemail_edit_contact', [ $this, 'edit_contact' ] );
        add_action( 'wp_ajax_pexemail_delete_contact', [ $this, 'delete_contact' ] );
        add_action( 'wp_ajax_pexemail_import_contacts', [ $this, 'import_contacts' ] );

        add_action( 'wp_ajax_pexemail_send_campaign_batch', [ $this, 'send_campaign_batch' ] );
        add_action( 'wp_ajax_pexemail_retry_failed_campaign', [ $this, 'retry_failed_campaign' ] );

        add_action( 'wp_ajax_pexemail_schedule_campaign', [ $this, 'schedule_campaign' ] );
        add_action( 'wp_ajax_pexemail_cancel_schedule', [ $this, 'cancel_schedule' ] );
    }

    private function verify_security( $nonce_action = 'pexemail_contacts_nonce' ) {
        check_ajax_referer( $nonce_action, '_ajax_nonce' );
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( 'Unauthorized access.' );
        }
    }

    public function create_list() {
        $this->verify_security( 'pexemail_contacts_nonce' );
        global $wpdb;
        $list_name = isset( $_POST['list_name'] ) ? sanitize_text_field( wp_unslash( $_POST['list_name'] ) ) : '';
        if ( empty( $list_name ) ) wp_send_json_error( 'List name is required.' );
        $wpdb->insert( $wpdb->prefix . 'pexemail_lists', [ 'name' => $list_name ], [ '%s' ] );
        wp_send_json_success( [ 'message' => 'List created successfully.' ] );
    }

    public function edit_list() {
        $this->verify_security( 'pexemail_contacts_nonce' );
        global $wpdb;
        $list_id   = isset( $_POST['list_id'] ) ? intval( $_POST['list_id'] ) : 0;
        $list_name = isset( $_POST['list_name'] ) ? sanitize_text_field( wp_unslash( $_POST['list_name'] ) ) : '';
        if ( $list_id > 0 && ! empty( $list_name ) ) {
            $wpdb->update( $wpdb->prefix . 'pexemail_lists', [ 'name' => $list_name ], [ 'id' => $list_id ], [ '%s' ], [ '%d' ] );
            wp_send_json_success();
        }
        wp_send_json_error( 'Invalid data provided.' );
    }

    public function delete_list() {
        $this->verify_security( 'pexemail_contacts_nonce' );
        global $wpdb;
        $list_id = isset( $_POST['list_id'] ) ? intval( $_POST['list_id'] ) : 0;
        if ( $list_id > 0 ) {
            $wpdb->delete( $wpdb->prefix . 'pexemail_lists', [ 'id' => $list_id ], [ '%d' ] );
            $wpdb->delete( $wpdb->prefix . 'pexemail_contacts', [ 'list_id' => $list_id ], [ '%d' ] );
        }
        wp_send_json_success();
    }

    public function add_single_contact() {
        $this->verify_security( 'pexemail_contacts_nonce' );
        global $wpdb;
        $list_id    = isset( $_POST['list_id'] ) ? intval( $_POST['list_id'] ) : 0;
        $raw_email  = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '';
        $first_name = isset( $_POST['first_name'] ) ? sanitize_text_field( wp_unslash( $_POST['first_name'] ) ) : '';
        $last_name  = isset( $_POST['last_name'] ) ? sanitize_text_field( wp_unslash( $_POST['last_name'] ) ) : '';

        if ( ! is_email( $raw_email ) ) wp_send_json_error( 'Invalid email address.' );

        $exists = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}pexemail_contacts WHERE list_id = %d AND LOWER(email) = %s", $list_id, strtolower( $raw_email ) ) );
        if ( $exists ) wp_send_json_error( 'Duplicate email in this list.' );

        $wpdb->insert( $wpdb->prefix . 'pexemail_contacts', [ 'list_id' => $list_id, 'email' => $raw_email, 'first_name' => $first_name, 'last_name' => $last_name, 'status' => 'subscribed' ], [ '%d', '%s', '%s', '%s', '%s' ] );
        wp_send_json_success();
    }

    public function edit_contact() {
        $this->verify_security( 'pexemail_contacts_nonce' );
        global $wpdb;
        $contact_id = isset( $_POST['contact_id'] ) ? intval( $_POST['contact_id'] ) : 0;
        $email      = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '';
        $first_name = isset( $_POST['first_name'] ) ? sanitize_text_field( wp_unslash( $_POST['first_name'] ) ) : '';
        $last_name  = isset( $_POST['last_name'] ) ? sanitize_text_field( wp_unslash( $_POST['last_name'] ) ) : '';

        if ( $contact_id <= 0 || ! is_email( $email ) ) wp_send_json_error( 'Invalid data.' );
        $wpdb->update( $wpdb->prefix . 'pexemail_contacts', [ 'email' => $email, 'first_name' => $first_name, 'last_name' => $last_name ], [ 'id' => $contact_id ], [ '%s', '%s', '%s' ], [ '%d' ] );
        wp_send_json_success();
    }

    public function delete_contact() {
        $this->verify_security( 'pexemail_contacts_nonce' );
        global $wpdb;
        $contact_id = isset( $_POST['contact_id'] ) ? intval( $_POST['contact_id'] ) : 0;
        if ( $contact_id > 0 ) $wpdb->delete( $wpdb->prefix . 'pexemail_contacts', [ 'id' => $contact_id ], [ '%d' ] );
        wp_send_json_success();
    }

    public function import_contacts() {
        $this->verify_security( 'pexemail_contacts_nonce' );
        global $wpdb;
        $list_id  = isset( $_POST['list_id'] ) ? intval( $_POST['list_id'] ) : 0;
        $contacts = isset( $_POST['contacts'] ) ? json_decode( wp_unslash( $_POST['contacts'] ), true ) : [];

        if ( $list_id <= 0 || empty( $contacts ) ) wp_send_json_error( 'Invalid data.' );

        $existing = $wpdb->get_col( $wpdb->prepare( "SELECT email FROM {$wpdb->prefix}pexemail_contacts WHERE list_id = %d", $list_id ) );
        $existing = array_flip( array_map( 'strtolower', $existing ) );

        foreach ( $contacts as $contact ) {
            $email = isset( $contact['email'] ) ? sanitize_email( $contact['email'] ) : '';
            if ( ! is_email( $email ) || isset( $existing[ strtolower( $email ) ] ) ) continue;

            $existing[ strtolower( $email ) ] = true;
            $wpdb->insert( $wpdb->prefix . 'pexemail_contacts', [
                'list_id'    => $list_id,
                'email'      => $email,
                'first_name' => isset( $contact['first_name'] ) ? sanitize_text_field( $contact['first_name'] ) : '',
                'last_name'  => isset( $contact['last_name'] ) ? sanitize_text_field( $contact['last_name'] ) : '',
                'status'     => 'subscribed'
            ], [ '%d', '%s', '%s', '%s', '%s' ] );
        }
        wp_send_json_success();
    }

    public function schedule_campaign() {
        $this->verify_security( 'pexemail_admin_nonce' );
        global $wpdb;
        $campaign_id = isset( $_POST['campaign_id'] ) ? intval( $_POST['campaign_id'] ) : 0;
        $date        = isset( $_POST['date'] ) ? sanitize_text_field( wp_unslash( $_POST['date'] ) ) : '';
        $time        = isset( $_POST['time'] ) ? sanitize_text_field( wp_unslash( $_POST['time'] ) ) : '';
        $timezone    = isset( $_POST['timezone'] ) ? sanitize_text_field( wp_unslash( $_POST['timezone'] ) ) : '';

        if ( $campaign_id <= 0 || empty( $date ) || empty( $time ) || empty( $timezone ) ) wp_send_json_error( 'Invalid schedule data.' );

        try {
            $tz = new DateTimeZone( $timezone );
            $dt = new DateTime( $date . ' ' . $time, $tz );
            $utc_timestamp = $dt->getTimestamp();
        } catch ( Exception $e ) {
            wp_send_json_error( 'Invalid format.' );
        }

        if ( $utc_timestamp < ( time() - 300 ) ) wp_send_json_error( 'Cannot schedule in the past.' );

        $columns = $wpdb->get_col( "DESC {$wpdb->prefix}pexemail_campaigns", 0 );
        if ( ! in_array( 'scheduled_at', $columns ) ) {
            $wpdb->query( "ALTER TABLE {$wpdb->prefix}pexemail_campaigns ADD COLUMN scheduled_at INT(11) DEFAULT 0" );
        }

        $wpdb->update( $wpdb->prefix . 'pexemail_campaigns', [ 'status' => 'scheduled', 'scheduled_at' => $utc_timestamp ], [ 'id' => $campaign_id ] );
        wp_send_json_success( [ 'message' => 'Scheduled.' ] );
    }

    public function cancel_schedule() {
        $this->verify_security( 'pexemail_admin_nonce' );
        global $wpdb;
        $campaign_id = isset( $_POST['campaign_id'] ) ? intval( $_POST['campaign_id'] ) : 0;
        $wpdb->update( $wpdb->prefix . 'pexemail_campaigns', [ 'status' => 'draft', 'scheduled_at' => 0 ], [ 'id' => $campaign_id ] );
        wp_send_json_success();
    }

    public function send_campaign_batch() {
        $this->verify_security( 'pexemail_admin_nonce' );
        global $wpdb;
        
        $campaign_id = isset( $_POST['campaign_id'] ) ? intval( $_POST['campaign_id'] ) : 0;
        
        $batch_size = 10; 

        $campaign = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}pexemail_campaigns WHERE id = %d", $campaign_id));
        if (!$campaign) wp_send_json_error('Campaign not found.');

        if ($campaign->status === 'scheduled') {
            $wpdb->update($wpdb->prefix . 'pexemail_campaigns', ['status' => 'draft', 'scheduled_at' => 0], ['id' => $campaign_id]);
        }

        $recipients = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}pexemail_recipients WHERE campaign_id = %d AND status = 'pending' LIMIT %d", $campaign_id, $batch_size));

        if (empty($recipients)) {
            $wpdb->update($wpdb->prefix . 'pexemail_campaigns', ['status' => 'completed'], ['id' => $campaign_id]);
            wp_send_json_success(['status' => 'completed']);
        }

        $settings = get_option('pexemail_settings', []);
        $license_key = get_option('pexemail_license_key', '');
        $sender_email = !empty($settings['sender_email']) ? $settings['sender_email'] : get_option('admin_email');

        $wrapped_template = $this->wrap_email_html( stripslashes($campaign->template), stripslashes($campaign->subject) );
        
        $pixel_url = rest_url("pex-campaign/v1/track/open/{$campaign->id}/{{rec_id}}/{{sec_hash}}");
        
        $tracking_pixel = '<img src="' . esc_url($pixel_url) . '" width="1" height="1" alt="" role="presentation" style="border:none; margin:0; padding:0;" />';
        
        // FIX: Safely build tracking URLs using add_query_arg to support all permalink structures
        $body = preg_replace_callback('/<a[^>]+href=["\']([^"\']+)["\'][^>]*>(.*?)<\/a>/is', function($matches) use($campaign) {
            $original_url = $matches[1];
            $inner_text   = strip_tags($matches[2]);
            
            if(strpos($original_url, '#') === 0 || strpos($original_url, 'mailto:') === 0 || strpos($original_url, 'facebook.com') !== false || strpos($original_url, 'x.com') !== false || strpos($original_url, 'linkedin.com') !== false || strpos($original_url, 'instagram.com') !== false || strpos($original_url, 'youtube.com') !== false || strpos($original_url, 't.me') !== false) {
                return $matches[0];
            }

            if ( filter_var( trim( $inner_text ), FILTER_VALIDATE_URL ) ) {
                return $matches[0];
            }

            $clean_url = html_entity_decode($original_url, ENT_QUOTES, 'UTF-8');
            
            // Generate base REST route
            $base_track_url = rest_url("pex-campaign/v1/track/click/{$campaign->id}/{{rec_id}}/{{sec_hash}}");
            
            // Safely append the target URL parameter
            $tracked_url = add_query_arg('url', urlencode($clean_url), $base_track_url);
            
            return str_replace($original_url, $tracked_url, $matches[0]);
        }, $wrapped_template);

        $plain_text_body = wp_strip_all_tags( str_replace( ['<br>', '<br/>', '</p>', '</tr>', '</td>'], "\n", $body ) );
        $plain_text_body = preg_replace("/\n\s+/", "\n", $plain_text_body);
        $plain_text_body = trim($plain_text_body);

        $body .= $tracking_pixel;

        require_once PEXEMAIL_DIR . 'includes/class-pexemail-tracking.php';
        $payload_recipients = [];

        foreach ($recipients as $recipient) {
            $payload_recipients[] = [
                'id'         => $recipient->id,
                'email'      => $recipient->email,
                'first_name' => $recipient->first_name,
                'last_name'  => $recipient->last_name,
                'sec_hash'   => PexEmail_Tracking::generate_tracking_hash( $campaign->id, $recipient->id )
            ];
        }

        $payload = [
            'license_key'   => $license_key,
            'sender_email'  => $sender_email,
            'subject'       => stripslashes($campaign->subject),
            'body'          => $body,
            'body_text'     => $plain_text_body, 
            'recipients'    => $payload_recipients,
            'smtp_settings' => $settings
        ];

        $response = wp_remote_post( 'https://payment.pexally.com/wp-json/pexally-email-engine/v1/queue-campaign', [
            'timeout'     => 45, 
            'headers'     => [ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ],
            'body'        => wp_json_encode( $payload ),
        ]);

        if ( is_wp_error( $response ) ) {
            wp_send_json_error( 'Failed to connect to Pexally servers. Please try again later.' );
        }

        $status_code = wp_remote_retrieve_response_code( $response );
        $body_response = json_decode( wp_remote_retrieve_body( $response ), true );

        if ( $status_code === 403 || $status_code === 400 || ( isset($body_response['success']) && $body_response['success'] === false ) ) {
            $msg = isset($body_response['message']) ? $body_response['message'] : 'Daily limit reached or configuration error.';
            wp_send_json_error( $msg );
        }

        foreach ($recipients as $recipient) {
            $wpdb->update(
                $wpdb->prefix . 'pexemail_recipients', 
                ['status' => 'sent'], 
                ['id' => $recipient->id],
                ['%s'],
                ['%d']
            );
        }

        $remaining = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->prefix}pexemail_recipients WHERE campaign_id = %d AND status = 'pending'", $campaign_id));
        
        wp_send_json_success([
            'status'               => 'processing', 
            'remaining'            => $remaining,
            'sent_this_batch'      => count($recipients),
            'processed_this_batch' => count($recipients)
        ]);
    }

    public function retry_failed_campaign() {
        $this->verify_security( 'pexemail_admin_nonce' );
        global $wpdb;
        $campaign_id = isset($_POST['campaign_id']) ? intval($_POST['campaign_id']) : 0;
        $wpdb->update( $wpdb->prefix . 'pexemail_recipients', ['status' => 'pending'], ['campaign_id' => $campaign_id, 'status' => 'failed'] );
        $wpdb->update( $wpdb->prefix . 'pexemail_campaigns', ['status' => 'draft'], ['id' => $campaign_id] );
        wp_send_json_success();
    }

    public function wrap_email_html($body_content, $email_title = '') {
        $settings = get_option('pexemail_settings', []);
        $logo_url = !empty($settings['logo_url']) ? esc_url($settings['logo_url']) : '';
        $footer_contact = !empty($settings['footer_contact_text']) ? wp_kses_post(wpautop(stripslashes($settings['footer_contact_text']))) : '';
        
        $socials = '';
        $assets_url = PEXEMAIL_URL . 'assets/images/';
        $social_links =[ 'facebook_url'=>'fb.png', 'x_url'=>'x.png', 'linkedin_url'=>'li.png', 'instagram_url'=>'ig.png', 'youtube_url'=>'yt.png', 'telegram_url'=>'telegram.png' ];

        foreach ($social_links as $key => $icon) {
            if (!empty($settings[$key])) {
                $socials .= '<a href="'.esc_url($settings[$key]).'" style="display:inline-block; margin-right:12px; text-decoration:none;"><img src="' . esc_url($assets_url . $icon) . '" width="28" height="28" alt="" style="display:block; border:0;"></a>';
            }
        }

        $body_content = wpautop( wp_specialchars_decode((string) $body_content, ENT_QUOTES) );

        $header_logo_row = $logo_url ? '<tr><td align="center" style="background-color:#0f172a; padding:35px 20px; text-align:center; border-bottom:4px solid #10b981; border-radius:12px 12px 0 0;"><img src="'.$logo_url.'" alt="Brand Logo" style="max-width:180px; height:auto; display:inline-block; border:none; outline:none; text-decoration:none;"></td></tr>' : '';
        $footer_block_row = ($footer_contact || $socials) ? '<tr><td align="center" style="padding:35px 34px; background-color:#f8fafc; border-top:1px solid #e2e8f0; font-size:14px; line-height:1.6; color:#64748b; text-align:center; border-radius:0 0 12px 12px;">'.$footer_contact.'<div style="margin-top:18px;">'.$socials.'</div></td></tr>' : '';

        return '<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>'.esc_html($email_title).'</title></head><body style="margin:0;padding:0;background-color:#f3f4f6;font-family:-apple-system,BlinkMacSystemFont,\'Segoe UI\',Roboto,Helvetica,Arial,sans-serif;color:#374151;"><table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="background-color:#f3f4f6;margin:0;padding:40px 15px;"><tr><td align="center"><table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="max-width:600px;background-color:#ffffff;border-radius:12px;border:1px solid #e5e7eb;box-shadow:0 10px 25px rgba(0,0,0,0.05); text-align:left; border-spacing:0; border-collapse:separate;">'.$header_logo_row.'<tr><td style="padding:45px 40px; font-size:15.5px; line-height:1.7; color:#334155;">'.$body_content.'</td></tr>'.$footer_block_row.'</table></td></tr></table></body></html>';
    }
}