<?php

declare(strict_types=1);

namespace MailerPress\Actions\ActionScheduler\Processors;

\defined('ABSPATH') || exit;

use MailerPress\Core\Attributes\Action;
use MailerPress\Core\Enums\Tables;
use MailerPress\Models\CustomFields;

class ProcessChunkImportContact
{
    #[Action('process_import_chunk', priority: 10, acceptedArgs: 2)]
    public function processImportChunk($chunk_id, $forceUpdate): void
    {
        global $wpdb;
        $importChunks = Tables::get(Tables::MAILERPRESS_IMPORT_CHUNKS);
        $contactTable = Tables::get(Tables::MAILERPRESS_CONTACT);
        $contactBatch = Tables::get(Tables::MAILERPRESS_CONTACT_BATCHES);

        // Fetch the chunk data from the database
        $chunk = $wpdb->get_row($wpdb->prepare("
	        SELECT * FROM {$importChunks}
	        WHERE id = %d AND processed = 0
	    ", $chunk_id));

        $batch = $wpdb->get_row(
            $wpdb->prepare("SELECT * FROM {$contactBatch} WHERE batch_id = %d", $chunk->batch_id),
            ARRAY_A
        );

        if (!$batch) {
            return;
        }

        $contactTags = json_decode($batch['tags'], true);
        $contactLists = json_decode($batch['lists'], true);
        $contact_status = $batch['subscription_status'];

        if ($chunk) {
            $contacts = json_decode($chunk->chunk_data, true);

            foreach ($contacts as $contact) {
                $contact_id = $wpdb->get_var(
                    $wpdb->prepare(
                        "SELECT contact_id FROM {$contactTable} WHERE email = %s LIMIT 1",
                        $contact['email']
                    )
                );

                if (null === $contact_id) {
                    // Insert new contact
                    // Extract and clean first_name and last_name
                    // Handle both array_key_exists and isset to catch empty strings
                    $first_name = '';
                    $last_name = '';

                    if (array_key_exists('first_name', $contact)) {
                        $first_name = is_string($contact['first_name']) ? trim($contact['first_name'], ' "\'') : '';
                    }

                    if (array_key_exists('last_name', $contact)) {
                        $last_name = is_string($contact['last_name']) ? trim($contact['last_name'], ' "\'') : '';
                    }

                    $contact_data = [
                        'email' => $contact['email'],
                        'first_name' => sanitize_text_field($first_name),
                        'last_name' => sanitize_text_field($last_name),
                        'subscription_status' => $contact_status ?? 'pending',
                        'unsubscribe_token' => wp_generate_uuid4(),
                        'created_at' => current_time('mysql'),
                        'updated_at' => current_time('mysql'),
                        'opt_in_source' => 'batch_import_file',
                        'access_token' => bin2hex(random_bytes(32))
                    ];

                    $result = $wpdb->insert($contactTable, $contact_data);

                    if (false !== $result) {
                        $contactId = $wpdb->insert_id;

                        // Insert tags
                        foreach ($contactTags as $tag) {
                            $wpdb->insert(Tables::get(Tables::CONTACT_TAGS), [
                                'contact_id' => $contactId,
                                'tag_id' => $tag['id'],
                            ]);
                        }

                        // Insert lists
                        foreach ($contactLists as $list) {
                            $wpdb->insert(Tables::get(Tables::MAILERPRESS_CONTACT_LIST), [
                                'contact_id' => $contactId,
                                'list_id' => $list['id'],
                            ]);
                        }

                        // Insert custom fields - skip standard fields that shouldn't be in custom_fields
                        if (!empty($contact['custom_fields']) && is_array($contact['custom_fields'])) {
                            $standardFields = ['email', 'first_name', 'last_name', 'created_at', 'updated_at'];
                            foreach ($contact['custom_fields'] as $field_key => $field_value) {
                                // Skip if this is a standard field (shouldn't be in custom_fields)
                                if (in_array($field_key, $standardFields, true)) {
                                    continue;
                                }

                                // Sanitize value according to field type
                                $sanitized_value = CustomFields::sanitizeValue($field_key, $field_value);

                                // Skip null values (empty or invalid)
                                if ($sanitized_value === null) {
                                    continue;
                                }

                                // Convert to string for database storage (handles int, float, string, etc.)
                                $db_value = is_numeric($sanitized_value)
                                    ? (string) $sanitized_value
                                    : sanitize_text_field((string) $sanitized_value);

                                $wpdb->insert(Tables::get(Tables::MAILERPRESS_CONTACT_CUSTOM_FIELDS), [
                                    'contact_id' => $contactId,
                                    'field_key' => sanitize_text_field($field_key),
                                    'field_value' => $db_value,
                                ]);
                            }
                        }

                        $wpdb->query(
                            $wpdb->prepare(
                                "UPDATE {$contactBatch} SET processed_count = processed_count + 1 WHERE batch_id = %d",
                                $chunk->batch_id
                            )
                        );
                    }
                } else {
                    // Update existing contact
                    if (true === $forceUpdate || '1' === $forceUpdate) {
                        // Extract and clean first_name and last_name
                        // Handle both array_key_exists and isset to catch empty strings
                        $first_name = '';
                        $last_name = '';

                        if (array_key_exists('first_name', $contact)) {
                            $first_name = is_string($contact['first_name']) ? trim($contact['first_name'], ' "\'') : '';
                        }

                        if (array_key_exists('last_name', $contact)) {
                            $last_name = is_string($contact['last_name']) ? trim($contact['last_name'], ' "\'') : '';
                        }

                        $result = $wpdb->update(
                            $contactTable,
                            [
                                'subscription_status' => $contact_status,
                                'updated_at' => current_time('mysql'),
                                'first_name' => sanitize_text_field($first_name),
                                'last_name' => sanitize_text_field($last_name),
                            ],
                            ['contact_id' => $contact_id]
                        );

                        if (false !== $result) {
                            // Insert custom fields for existing contact (update if exists)
                            if (!empty($contact['custom_fields']) && is_array($contact['custom_fields'])) {
                                $standardFields = ['email', 'first_name', 'last_name', 'created_at', 'updated_at'];
                                foreach ($contact['custom_fields'] as $field_key => $field_value) {
                                    // Skip if this is a standard field (shouldn't be in custom_fields)
                                    if (in_array($field_key, $standardFields, true)) {
                                        continue;
                                    }

                                    $existing = $wpdb->get_var(
                                        $wpdb->prepare(
                                            "SELECT field_id FROM " . Tables::get(Tables::MAILERPRESS_CONTACT_CUSTOM_FIELDS) . " WHERE contact_id = %d AND field_key = %s LIMIT 1",
                                            $contact_id,
                                            $field_key
                                        )
                                    );

                                    // Sanitize value according to field type
                                    $sanitized_value = CustomFields::sanitizeValue($field_key, $field_value);

                                    // Skip null values (empty or invalid)
                                    if ($sanitized_value === null) {
                                        // Delete existing field if value is empty
                                        if ($existing) {
                                            $wpdb->delete(
                                                Tables::get(Tables::MAILERPRESS_CONTACT_CUSTOM_FIELDS),
                                                ['field_id' => $existing]
                                            );
                                        }
                                        continue;
                                    }

                                    // Convert to string for database storage (handles int, float, string, etc.)
                                    $db_value = is_numeric($sanitized_value)
                                        ? (string) $sanitized_value
                                        : sanitize_text_field((string) $sanitized_value);

                                    if ($existing) {
                                        $wpdb->update(
                                            Tables::get(Tables::MAILERPRESS_CONTACT_CUSTOM_FIELDS),
                                            ['field_value' => $db_value],
                                            ['field_id' => $existing]
                                        );
                                    } else {
                                        $wpdb->insert(
                                            Tables::get(Tables::MAILERPRESS_CONTACT_CUSTOM_FIELDS),
                                            [
                                                'contact_id' => $contact_id,
                                                'field_key' => sanitize_text_field($field_key),
                                                'field_value' => $db_value,
                                            ]
                                        );
                                    }
                                }
                            }
                        }
                    }

                    $wpdb->query(
                        $wpdb->prepare(
                            "UPDATE {$contactBatch} SET processed_count = processed_count + 1 WHERE batch_id = %d",
                            $chunk->batch_id
                        )
                    );
                }
            }

            // Mark the chunk as processed
            $wpdb->update($importChunks, ['processed' => 1], ['id' => $chunk_id]);

            // Check if all chunks for this batch are processed
            $remaining_chunks = $wpdb->get_var($wpdb->prepare("
	            SELECT COUNT(*) FROM {$importChunks}
	            WHERE batch_id = %d AND processed = 0
	        ", $chunk->batch_id));

            if (0 === (int) $remaining_chunks) {
                // Mark batch as completed
                $wpdb->update($contactBatch, ['status' => 'done'], ['batch_id' => $chunk->batch_id]);
            }
        }
    }
}
