<?php

namespace App\Console\Commands;

use App\Order;
use App\Jobs\CancelExpiredProvisionalOrders;
use App\Services\IdentityVerificationService;
use Illuminate\Console\Command;

class CancelExpiredProvisionalOrdersCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'orders:cancel-expired-provisional
                            {--sync : Run synchronously instead of dispatching to queue}
                            {--code= : Cancel a specific order by code (for testing purposes)}
                            {--force : Skip confirmation when using --code}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Cancel provisional orders that have expired due to identity verification timeout';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @param IdentityVerificationService $service
     * @return int
     */
    public function handle(IdentityVerificationService $service)
    {
        // Check if specific order code is provided (for testing)
        $orderCode = $this->option('code');

        if ($orderCode) {
            return $this->cancelSpecificOrder($service, $orderCode);
        }

        $this->info('Checking for expired provisional orders...');

        if ($this->option('sync')) {
            // Run synchronously
            $result = $service->cancelExpiredProvisionalOrders();

            $this->info("Cancelled {$result['cancelled_count']} expired provisional orders.");

            if (!empty($result['errors'])) {
                $this->warn('Some orders failed to cancel:');
                foreach ($result['errors'] as $error) {
                    $this->error("Order #{$error['order_id']}: {$error['error']}");
                }
            }
        } else {
            // Dispatch to queue
            CancelExpiredProvisionalOrders::dispatch();
            $this->info('Job dispatched to queue.');
        }

        return 0;
    }

    /**
     * Cancel a specific order by code (for testing purposes)
     *
     * @param IdentityVerificationService $service
     * @param string $orderCode
     * @return int
     */
    protected function cancelSpecificOrder(IdentityVerificationService $service, string $orderCode): int
    {
        $this->info("Looking for order with code: {$orderCode}");

        $order = Order::where('code', $orderCode)->first();

        if (!$order) {
            $this->error("Order with code '{$orderCode}' not found.");
            return 1;
        }

        $this->info("Found order #{$order->id}");
        $this->info("  - User ID: {$order->user_id}");
        $this->info("  - Status: {$order->status}");
        $this->info("  - Is Provisional: " . ($order->isProvisional() ? 'Yes' : 'No'));
        $this->info("  - Auto Cancelled: " . ($order->auto_cancelled ? 'Yes' : 'No'));

        // Check if order is already cancelled
        if ($order->status == Order::STATUS_CANCELLED) {
            $this->warn("Order is already cancelled.");
            return 1;
        }

        // Check if order is provisional (status = 9)
        if (!$order->isProvisional()) {
            $this->warn("Order is not a provisional order. Only provisional orders can be cancelled with this command.");
            return 1;
        }

        // Confirm before cancelling (skip if --force is used)
        if (!$this->option('force') && !$this->confirm("Are you sure you want to cancel this order? This will send a cancellation email to the customer.")) {
            $this->info("Cancelled by user.");
            return 0;
        }

        try {
            $reason = '本人確認書類の提出期限が過ぎたため、自動キャンセルされました';
            $service->cancelProvisionalOrder($order, $reason);

            $this->info("✓ Order #{$order->id} (code: {$orderCode}) has been cancelled successfully.");
            $this->info("✓ Cancellation email has been queued for sending.");

            return 0;
        } catch (\Exception $e) {
            $this->error("Failed to cancel order: " . $e->getMessage());
            return 1;
        }
    }
}
