<?php

namespace WPIS;

require_once __DIR__ . '/SyncManager.php';

class WpCliManager
{

    private const COMMAND = 'wpis sync';
    private const OPERATIONS = ['import', 'update', 'delete'];

    public static function init(): void
    {
        if (!defined('WP_CLI') || !WP_CLI || !class_exists('\WP_CLI')) {
            return;
        }

        \WP_CLI::add_command(self::COMMAND, [self::class, 'sync']);
    }

    /**
     * Run an ImmoSync sync operation.
     *
     * ## OPTIONS
     *
     * <operation>
     * : Operation to run (`import`, `update`, `delete`).
     *
     * [--force-images]
     * : Force image import during import operation.
     *
     * ## EXAMPLES
     *
     *     wp wpis sync import
     *     wp wpis sync import --force-images
     *     wp wpis sync update
     *     wp wpis sync delete
     */
    public static function sync(array $args, array $assocArgs): void
    {

        $_SERVER['HTTP_HOST'] = 'localhost:8100';
        $_SERVER['SERVER_PORT'] = 8100;

        $operation = isset($args[0]) ? strtolower((string) $args[0]) : '';

        if (!in_array($operation, self::OPERATIONS, true)) {
            \WP_CLI::error('Invalid operation. Allowed values: import, update, delete.');
            return;
        }

        switch ($operation) {
            case 'import':
                self::runImport($assocArgs);
                break;
            case 'update':
                self::runUpdate();
                break;
            case 'delete':
                self::runDelete();
                break;
        }
    }

    private static function runImport(array $assocArgs): void
    {
        $syncManager = SyncManager::init();
        $settings = (object) [
            'forceImportImages' => \WP_CLI\Utils\get_flag_value($assocArgs, 'force-images', false),
            'origin' => 'wp-cli',
        ];

        $importedCount = 0;
        $start = microtime(true);

        do {
            $result = $syncManager->next($settings);

            if (isset($result['success']) && !$result['success']) {
                \WP_CLI::error($result['message'] ?? 'Import failed : ' . json_encode($result));
                return;
            }

            if (!empty($result['lastImport'])) {
                $importedCount++;
                \WP_CLI::log(
                    sprintf(
                        'Imported estate %s (post %s).',
                        $result['lastImport']['estateId'] ?? 'n/a',
                        $result['lastImport']['postId'] ?? 'n/a'
                    )
                );
            }
        } while (empty($result['isComplete']));

        if (isset($syncManager->cache)) {
            $syncManager->cache->flush();
        }

        \WP_CLI::success(
            sprintf(
                'Import completed. Estates imported: %d. Duration: %.3fs.',
                $importedCount,
                microtime(true) - $start
            )
        );
    }

    private static function runUpdate(): void
    {
        $syncManager = SyncManager::init();
        $start = microtime(true);
        $result = $syncManager->updateStart();

        if (isset($result['success']) && !$result['success']) {
            \WP_CLI::error($result['message'] ?? 'Update failed.');
            return;
        }

        if (isset($syncManager->cache)) {
            $syncManager->cache->flush();
        }

        \WP_CLI::success(
            sprintf(
                'Update completed. Estates updated: %d. Duration: %.3fs.',
                (int) ($result['estatesUpdatedCount'] ?? 0),
                microtime(true) - $start
            )
        );
    }

    private static function runDelete(): void
    {
        $syncManager = SyncManager::init();
        $start = microtime(true);
        $result = $syncManager->removeEstates();

        if (isset($result['success']) && !$result['success']) {
            \WP_CLI::error($result['message'] ?? 'Delete failed.');
            return;
        }

        \WP_CLI::success(
            sprintf(
                'Delete completed. Estates removed: %d. Duration: %.3fs.',
                (int) ($result['estatesRemoved'] ?? 0),
                microtime(true) - $start
            )
        );
    }
}
