<?php
// EN: If this file is called directly, abort.
// IT: Se questo file viene chiamato direttamente, interrompi.
if (! defined('ABSPATH')) exit; // Exit

/**
 * FILE: class-pk-inex-run-miogest-houzez.php
 * FROM → admin/run-quick-import.php
 *         → chiamata diretta dal flusso di interfaccia (admin)
 * GOES TO → class-pkinex-import-miogest-houzez.php (gestione import)
 *           → class-pkinex-update-miogest-houzez.php (gestione aggiornamento)
 *           → class-pkinex-delete-real-houzez.php (gestione rimozione comuni)
 *
 * EN:
 *   Runner for Miogest → Houzez.
 *   Extends the abstract "Preparer" class and exposes:
 *   - a legacy one-shot method: pkinex_runner_miogest_houzez()
 *   - async-friendly batch methods:
 *       * pkinex_runner_miogest_houzez_batch()
 *       * pkinex_runner_miogest_houzez_update_batch()
 *   - a synchronous delete method for the step engine:
 *       * pkinex_run_delete_sync()
 *
 * IT:
 *   Runner per Miogest → Houzez.
 *   Estende la classe astratta "Preparer" ed espone:
 *   - un metodo legacy “one shot”: pkinex_runner_miogest_houzez()
 *   - metodi compatibili con l’engine async a blocchi:
 *       * pkinex_runner_miogest_houzez_batch()
 *       * pkinex_runner_miogest_houzez_update_batch()
 *   - un metodo di delete sincrono per il motore a step:
 *       * pkinex_run_delete_sync()
 */

// EN: Required abstract base class for import preparation steps.
// IT: Carica la classe astratta base per i preparativi dell'importazione.
require_once PKINEX_INEXPRESS_DIR . 'includes/class-pkinex-preparer.php';

class PKINEX_RunnerMiogestHouzez extends PKINEX_Preparer
{
    /**
     * EN: Constructor. Passes input to parent class and stores parameters locally.
     * IT: Costruttore. Passa i dati alla classe padre e salva i parametri.
     */
    public function __construct($source_data, $id_name, $source_type)
    {
        parent::__construct($source_data, $id_name, $source_type);

        $this->source_data = $source_data; // EN: URL, text, file path, etc. | IT: URL, testo, percorso file, ecc.
        $this->id_name     = $id_name;
        $this->source_type = $source_type;
    }

    /**
     * EN: Batch-friendly runner for Miogest → Houzez imports.
     * IT: Runner compatibile con import a BLOCCHI per Miogest → Houzez.
     *
     * @param int $offset
     * @param int $limit
     *
     * @return array
     *     EN: ['offset' => int, 'limit' => int, 'import_done' => int, 'total' => int, 'batch_done' => bool, 'errors' => array]
     *     IT: ['offset' => int, 'limit' => int, 'import_done' => int, 'total' => int, 'batch_done' => bool, 'errors' => array]
     */
    public function pkinex_runner_miogest_houzez_batch(int $offset, int $limit): array
    {
        // 1) Normalizza offset/limit
        if ($offset < 0) {
            $offset = 0;
        }
        if ($limit <= 0) {
            $limit = 2; // Safe default, allineato a Real → Houzez
        }

        try {
            // 2) XML pronto
            $xml = $this->pkinex_get_data_ready();
            if (! $xml instanceof \SimpleXMLElement) {
                return array(
                    'offset'         => $offset,
                    'limit'          => $limit,
                    'import_done'    => 0,  // tentativi
                    'import_success' => 0,  // realmente importati
                    'total'          => 0,
                    'batch_done'     => true,
                    'errors'         => array('XML not loaded correctly in Miogest runner batch.'),
                );
            }

            // 3) Lista completa degli ID da importare
            $full_import_ids = $this->pkinex_get_id_import();
            if (! is_array($full_import_ids)) {
                $full_import_ids = (array) $full_import_ids;
            }

            $total_import = is_countable($full_import_ids)
                ? count($full_import_ids)
                : count($full_import_ids);

            if ($total_import === 0) {
                // Nulla da importare → batch concluso
                return array(
                    'offset'         => $offset,
                    'limit'          => $limit,
                    'import_done'    => 0,
                    'import_success' => 0,
                    'total'          => 0,
                    'batch_done'     => true,
                    'errors'         => array(),
                );
            }

            // Se l’offset supera il totale → non resta nulla
            if ($offset >= $total_import) {
                return array(
                    'offset'         => $offset,
                    'limit'          => $limit,
                    'import_done'    => 0,
                    'import_success' => 0,
                    'total'          => $total_import,
                    'batch_done'     => true,
                    'errors'         => array(),
                );
            }

            // 4) Fetta di ID per questo batch
            $batch_ids = array_slice($full_import_ids, $offset, $limit);

            if (empty($batch_ids)) {
                return array(
                    'offset'         => $offset,
                    'limit'          => $limit,
                    'import_done'    => 0,
                    'import_success' => 0,
                    'total'          => $total_import,
                    'batch_done'     => true,
                    'errors'         => array(),
                );
            }

            $attempted_in_batch = count($batch_ids);

            // 5) Include + istanzia ImportMiogestHouzez
            require_once __DIR__ . '/class-pkinex-import-miogest-houzez.php';

            $import = new PKINEX_ImportMiogestHouzez(
                $xml,
                $this->id_name,
                $batch_ids
            );

            // 6) Esegui l’import per questo sottoinsieme
            $import_success = (int) $import->pkinex_import_miogest_houzez();

            // 7) Fine globale? (basato sui tentativi)
            $new_offset = $offset + $attempted_in_batch;
            $batch_done = ($new_offset >= $total_import);

            return array(
                'offset'         => $offset,
                'limit'          => $limit,

                // Per il contatore globale / offset:
                'import_done'    => $attempted_in_batch,

                // Per le statistiche:
                'import_success' => $import_success,

                'total'          => $total_import,
                'batch_done'     => $batch_done,
                'errors'         => array(),
            );
        } catch (\Throwable $e) {
            return array(
                'offset'         => $offset,
                'limit'          => $limit,
                'import_done'    => 0,
                'import_success' => 0,
                'total'          => 0,
                'batch_done'     => true,
                'errors'         => array($e->getMessage()),
            );
        }
    }

    /**
     * EN: Execute one batch of UPDATE operations for existing properties (Miogest → Houzez).
     * IT: Esegue un batch di operazioni di UPDATE sugli immobili esistenti (Miogest → Houzez).
     */
    public function pkinex_runner_miogest_houzez_update_batch(int $offset, int $limit): array
    {
        if ($offset < 0) {
            $offset = 0;
        }
        if ($limit <= 0) {
            $limit = 2;
        }

        // EN: Default total, so it's visible also in catch.
        // IT: Totale di default, così è visibile anche nel catch.
        $total_to_update = 0;

        try {
            $xml = $this->pkinex_get_data_ready();
            if (! $xml instanceof \SimpleXMLElement) {
                return array(
                    'update_done'    => 0,
                    'update_success' => 0,
                    'total'          => 0,
                    'batch_done'     => true,
                    'errors'         => array('XML not loaded correctly in Miogest update batch.'),
                );
            }

            $full_update_ids = $this->pkinex_get_id_update();
            if (! is_array($full_update_ids)) {
                $full_update_ids = (array) $full_update_ids;
            }

            $total_to_update = is_countable($full_update_ids)
                ? count($full_update_ids)
                : count($full_update_ids);

           /*  error_log(
                '[PKINEX FREE] MIOGEST UPDATE BATCH DEBUG: ' .
                    'offset=' . $offset .
                    ' limit=' . $limit .
                    ' total_to_update=' . $total_to_update .
                    ' ids=' . json_encode($full_update_ids)
            ); */

            if ($total_to_update === 0) {
                return array(
                    'update_done'    => 0,
                    'update_success' => 0,
                    'total'          => 0,
                    'batch_done'     => true,
                    'errors'         => array(),
                );
            }

            if ($offset >= $total_to_update) {
                return array(
                    'update_done'    => 0,
                    'update_success' => 0,
                    'total'          => $total_to_update,
                    'batch_done'     => true,
                    'errors'         => array(),
                );
            }

            $batch_ids = array_slice($full_update_ids, $offset, $limit);

            if (empty($batch_ids)) {
                return array(
                    'update_done'    => 0,
                    'update_success' => 0,
                    'total'          => $total_to_update,
                    'batch_done'     => true,
                    'errors'         => array(),
                );
            }

            $attempted_in_batch = count($batch_ids);

            require_once __DIR__ . '/class-pkinex-update-miogest-houzez.php';

            $update = new PKINEX_UpdateMiogestHouzez(
                $xml,
                $this->id_name,
                $batch_ids
            );

            $updated_success = (int) $update->pkinex_update_miogest_houzez();

            $new_offset = $offset + $attempted_in_batch;
            $batch_done = ($new_offset >= $total_to_update);

            return array(
                'update_done'    => $attempted_in_batch,
                'update_success' => $updated_success,
                'total'          => $total_to_update,
                'batch_done'     => $batch_done,
                'errors'         => array(),
            );
        } catch (\Throwable $e) {
            /* error_log(
                '[PKINEX FREE] MIOGEST UPDATE BATCH EXCEPTION: ' .
                    'offset=' . $offset .
                    ' limit=' . $limit .
                    ' total_to_update=' . $total_to_update .
                    ' msg=' . $e->getMessage()
            ); */

            return array(
                'update_done'    => 0,
                'update_success' => 0,
                'total'          => $total_to_update,
                'batch_done'     => true,
                'errors'         => array($e->getMessage()),
            );
        }
    }

    /**
     * EN: Main runner method (legacy "one-shot") for Miogest → Houzez.
     * IT: Metodo principale legacy “one shot” per Miogest → Houzez.
     */
    public function pkinex_runner_miogest_houzez(): array
    {
        $ui = ! wp_doing_cron(); // true se chiamato da UI admin

        // 1) Validazione sorgente
        if (empty($this->source_data)) {
            if ($ui) {
                echo '<div class="notice notice-error"><p>❌ Devi fornire i dati (URL/testo/file).</p></div>';
            }
            return ['ok' => false, 'msg' => 'Sorgente vuota: manca URL/testo/file', 'stats' => []];
        }

        try {
            // 2) Parsing XML (una volta sola)
            $xml = $this->pkinex_get_data_ready();

            // 3) Calcolo liste ID
            $list_id_import = $this->pkinex_get_id_import();
            $list_id_update = $this->pkinex_get_id_update();
            $list_id_delete = $this->pkinex_get_id_delete();

            // 4) Include runner concreti
            require_once plugin_dir_path(__FILE__) . 'class-pkinex-import-miogest-houzez.php';
            require_once plugin_dir_path(__FILE__) . 'class-pkinex-update-miogest-houzez.php';
            require_once plugin_dir_path(__FILE__) . 'class-pkinex-delete-real-houzez.php';

            // 5) Istanzia handler
            $import = new PKINEX_ImportMiogestHouzez($xml, $this->id_name, $list_id_import);
            $update = new PKINEX_UpdateMiogestHouzez($xml, $this->id_name, $list_id_update);
            $delete = new PKINEX_DeleteRealHouzez($this->id_name, $list_id_delete);

            // 6) Esecuzione
            $rImport = $import->pkinex_import_miogest_houzez();
            $rUpdate = $update->pkinex_update_miogest_houzez();
            $rDelete = $delete->pkinex_delete_real_houzez();

            // 7) Statistiche normalizzate (robuste anche se i metodi non ritornano nulla)
            $stats = [
                'to_import'   => is_countable($list_id_import) ? count($list_id_import) : null,
                'to_update'   => is_countable($list_id_update) ? count($list_id_update) : null,
                'to_delete'   => is_countable($list_id_delete) ? count($list_id_delete) : null,

                'import_done' => is_int($rImport) ? $rImport : (is_array($rImport) && isset($rImport['done']) ? (int) $rImport['done'] : null),
                'update_done' => is_int($rUpdate) ? $rUpdate : (is_array($rUpdate) && isset($rUpdate['done']) ? (int) $rUpdate['done'] : null),
                'delete_done' => is_int($rDelete) ? $rDelete : (is_array($rDelete) && isset($rDelete['done']) ? (int) $rDelete['done'] : null),
            ];

            // 8) Esito: ok solo se c'è stato lavoro oppure tutto a posto
            $didSomething = ($stats['import_done'] ?? 0) || ($stats['update_done'] ?? 0) || ($stats['delete_done'] ?? 0);
            $msg = $didSomething ? 'Importazione Miogest → Houzez completata' : 'Nessuna azione necessaria';

            return ['ok' => true, 'msg' => $msg, 'stats' => $stats];
        } catch (\Throwable $e) {
            return ['ok' => false, 'msg' => 'Eccezione nel runner Miogest: ' . $e->getMessage(), 'stats' => []];
        }
    }

    /**
     * EN: Run delete phase synchronously (used by Pro step-based engine and async JS).
     * IT: Esegue la fase di delete in modo sincrono (usata dal motore Pro a step e dall’async JS).
     */
    public function pkinex_run_delete_sync(): int
    {
        // EN: Ensure XML is at least parsed once (pipeline consistency)
        // IT: Assicura che l’XML sia almeno parsato una volta (coerenza col resto del flusso)
        $xml = $this->pkinex_get_data_ready();

        // EN: Get list of IDs to delete
        // IT: Recupera la lista degli ID da cancellare
        $list_id_delete = $this->pkinex_get_id_delete();

        if (! is_array($list_id_delete) || empty($list_id_delete)) {
            return 0;
        }

        // EN: Include the concrete delete class (shared with Real → Houzez)
        // IT: Include la classe concreta per la cancellazione (condivisa con Real → Houzez)
        require_once __DIR__ . '/class-pkinex-delete-real-houzez.php';

        if (! class_exists('PKINEX_DeleteRealHouzez')) {
            return 0;
        }

        // EN: Instantiate the delete handler
        // IT: Istanzia l’handler di delete
        $delete = new PKINEX_DeleteRealHouzez(
            $this->id_name,
            $list_id_delete
        );

        try {
            $deleted_count = (int) $delete->pkinex_delete_real_houzez();

            return $deleted_count;
        } catch (\Throwable $e) {

            return 0;
        }
    }
}
