<?php
/**
 * Caterpoint Order Import Console Command
 *
 * @category    PortalPeople
 * @package     Caterpoint
 * @author      Portal People Development Team
 * @copyright   Copyright (c) 2026 Portal People (https://portalpeople.co.uk)
 */

namespace PortalPeople\caterpoint\commands;

use Yii;
use yii\console\Controller;
use yii\console\ExitCode;
use yii\helpers\Console;
use yii\helpers\Json;
use PortalPeople\caterpoint\Module;

/**
 * Caterpoint Order Import Command
 * 
 * Usage:
 *   php yii caterpoint/order-import               Import orders with stored cursor
 *   php yii caterpoint/order-import --dry-run     Preview import without persisting
 *   php yii caterpoint/order-import --limit=50    Import max 50 orders
 *   php yii caterpoint/order-import --reset       Reset cursor and import from start
 */
class OrderImportController extends Controller
{
    /**
     * @var bool Perform a dry run without persisting changes
     */
    public bool $dryRun = false;

    /**
     * @var int Maximum number of orders to import
     */
    public int $limit = 0;

    /**
     * @var bool Reset the import cursor and start from beginning
     */
    public bool $reset = false;

    /**
     * @var bool Verbose output
     */
    public bool $verbose = false;

    /**
     * @inheritdoc
     */
    public function options($actionId)
    {
        return array_merge(parent::options($actionId), [
            'dryRun',
            'limit',
            'reset',
            'verbose',
        ]);
    }

    /**
     * Get the module instance
     * 
     * @return Module|null
     */
    protected function getModule(): ?Module
    {
        try {
            return Yii::$app->getModule('caterpoint');
        } catch (\Exception $e) {
            $this->stderr("Error: Could not load caterpoint module - " . $e->getMessage() . "\n", Console::FG_RED);
            return null;
        }
    }

    /**
     * Import orders from Caterpoint
     * 
     * @return int Exit code
     */
    public function actionIndex(): int
    {
        $module = $this->getModule();
        if ($module === null) {
            return ExitCode::UNSPECIFIED_ERROR;
        }

        if (!$module->isConfigured()) {
            $this->stderr("Error: Caterpoint module is not configured.\n", Console::FG_RED);
            $this->stderr("Please set apiEndpoint and apiToken in your configuration.\n");
            return ExitCode::UNSPECIFIED_ERROR;
        }

        $this->stdout("Starting Caterpoint order import...\n", Console::FG_CYAN);

        if ($this->dryRun) {
            $this->stdout("(DRY RUN - NO CHANGES WILL BE PERSISTED)\n", Console::FG_YELLOW);
        }

        // Reset cursor if requested
        if ($this->reset) {
            $service = $module->createOrderImportService();
            $service->cursorStore->clear();
            $this->stdout("✓ Import cursor cleared\n", Console::FG_GREEN);
        }

        try {
            $service = $module->createOrderImportService();
            $result = $service->run(
                null,
                $this->limit,
                $this->dryRun
            );

            $this->displayResult($result);
            return ExitCode::OK;
        } catch (\Throwable $e) {
            $this->stderr("Error during import: " . $e->getMessage() . "\n", Console::FG_RED);
            if ($this->verbose) {
                $this->stderr($e->getTraceAsString() . "\n");
            }
            return ExitCode::UNSPECIFIED_ERROR;
        }
    }

    /**
     * Display import results
     * 
     * @param array $result Import result summary
     */
    private function displayResult(array $result): void
    {
        $this->stdout("\n═══════════════════════════════════════════════════════════════\n", Console::FG_CYAN);
        $this->stdout("IMPORT SUMMARY\n", Console::FG_CYAN);
        $this->stdout("═══════════════════════════════════════════════════════════════\n", Console::FG_CYAN);

        $this->stdout("Fetched:      ");
        $this->stdout($result['fetched'] . "\n", Console::FG_CYAN);

        $this->stdout("Processed:    ");
        $this->stdout($result['processed'] . "\n", Console::FG_CYAN);

        $this->stdout("Created:      ");
        $this->stdout($result['created'] . "\n", Console::FG_GREEN);

        $this->stdout("Updated:      ");
        $this->stdout($result['updated'] . "\n", Console::FG_GREEN);

        $this->stdout("Failed:       ");
        $failureColor = $result['failed'] > 0 ? Console::FG_RED : Console::FG_GREEN;
        $this->stdout($result['failed'] . "\n", $failureColor);

        $this->stdout("Marked Exported: ");
        $this->stdout(($result['markedExported'] ?? 0) . "\n", Console::FG_GREEN);

        $this->stdout("Export Failed:   ");
        $this->stdout(($result['exportFailed'] ?? 0) . "\n", Console::FG_YELLOW);

        if ($result['dryRun']) {
            $this->stdout("Mode:         ");
            $this->stdout("DRY RUN\n", Console::FG_YELLOW);
        }

        if (!empty($result['nextCursor'])) {
            $this->stdout("Next Cursor:  ");
            $this->stdout($result['nextCursor'] . "\n", Console::FG_CYAN);
        }

        if (!empty($result['errors'])) {
            $this->stdout("\n" . count($result['errors']) . " Errors:\n", Console::FG_RED);
            foreach ($result['errors'] as $error) {
                $this->stderr("  • " . $error['message'] . "\n");
                if ($this->verbose && isset($error['order'])) {
                    $this->stderr("    Order: " . Json::encode($error['order']) . "\n");
                }
            }
        }

        $this->stdout("\n═══════════════════════════════════════════════════════════════\n", Console::FG_CYAN);
    }
}
