<?php

use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schedule;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Schema;

/*
|--------------------------------------------------------------------------
| Console Routes
|--------------------------------------------------------------------------
|
| This file is where you may define all of your Closure based console
| commands. Each Closure is bound to a command instance allowing a
| simple approach to interacting with each command's IO methods.
|
*/

Artisan::command('inspire', function () {
    $this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote')->hourly();

Artisan::command('app:migrate-safe {--allow-risky : Allow risky pending migrations} {--force-run : Execute migrate after checks}', function () {
    $this->info('Production-safe migration preflight');

    $migrationTableExists = Schema::hasTable('migrations');
    $ran = $migrationTableExists
        ? DB::table('migrations')->pluck('migration')->all()
        : [];

    $allFiles = collect(File::files(database_path('migrations')))
        ->filter(fn ($file) => $file->getExtension() === 'php')
        ->sortBy(fn ($file) => $file->getFilename())
        ->values();

    $pending = $allFiles->filter(function ($file) use ($ran) {
        return !in_array(pathinfo($file->getFilename(), PATHINFO_FILENAME), $ran, true);
    })->values();

    if ($pending->isEmpty()) {
        $this->info('No pending migrations.');
        return self::SUCCESS;
    }

    $this->line('Pending migrations:');
    foreach ($pending as $file) {
        $this->line(' - ' . $file->getFilename());
    }

    $riskyPatterns = [
        '/->delete\(/i',
        '/truncate\(/i',
        '/Schema::drop/i',
        '/dropColumn\(/i',
        '/renameColumn\(/i',
    ];

    $risky = [];
    foreach ($pending as $file) {
        $content = File::get($file->getPathname());
        foreach ($riskyPatterns as $pattern) {
            if (preg_match($pattern, $content) === 1) {
                $risky[] = $file->getFilename();
                break;
            }
        }
    }

    if (!empty($risky)) {
        $this->warn('Risky operations detected in pending migrations:');
        foreach ($risky as $name) {
            $this->warn(' - ' . $name);
        }

        if (!$this->option('allow-risky')) {
            $this->error('Blocked for safety. Review these migrations and rerun with --allow-risky only if approved.');
            return self::FAILURE;
        }
    }

    if (!$this->option('force-run')) {
        $this->comment('Dry run complete. To execute, run: php artisan app:migrate-safe --force-run' . (!empty($risky) ? ' --allow-risky' : ''));
        return self::SUCCESS;
    }

    if (!$this->confirm('Have you taken a database backup and confirmed rollback plan?')) {
        $this->error('Aborted. Take backup first.');
        return self::FAILURE;
    }

    $this->info('Running php artisan migrate --force ...');
    $exit = Artisan::call('migrate', ['--force' => true]);
    $this->line(Artisan::output());

    return $exit === 0 ? self::SUCCESS : self::FAILURE;
})->purpose('Preflight check and safe execution for production migrations');

// Schedule cleanup of expired stock reservations every 5 minutes
Schedule::command('inventory:cleanup-expired-reservations')
    ->everyFiveMinutes()
    ->withoutOverlapping();

// Cancel stale unpaid orders that remained in awaiting_payment for 4 hours.
Schedule::command('orders:cancel-expired-awaiting-payment')
    ->everyTenMinutes()
    ->withoutOverlapping();

// System health monitoring
Schedule::command('monitor:health')
    ->hourly()
    ->withoutOverlapping();

// Sync Delhivery API delivery status every 1 hour
Schedule::command('delhivery:sync-delivery-status')
    ->hourly()
    ->withoutOverlapping();

// Sync Ekart API delivery status every 1 hour
Schedule::command('ekart:sync-delivery-status')
    ->hourly()
    ->withoutOverlapping();

// Auto-deliver manual carrier shipments after 5 days
Schedule::command('orders:auto-deliver-manual-shipments')
    ->daily()
    ->withoutOverlapping();

// Daily payment health summary and hard-fail alert
Schedule::command('payments:health-report')
    ->dailyAt('00:15')
    ->withoutOverlapping();

// Process ticket inactivity reminders and auto-closes.
Schedule::command('tickets:process-auto-close')
    ->hourly()
    ->withoutOverlapping();
