<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Log;

class RunAllCronTasks extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'cron:all';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Run ALL scheduled cron tasks in one go (auto tasks, ROI, crypto prices, market update, copy trading, giveaways, notifications cleanup)';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $startTime = microtime(true);
        $results = [];

        $tasks = [
            ['command' => 'auto:run-tasks',             'label' => 'Auto Tasks (ROI, Trading, Copy, Bot, Demo)'],
            ['command' => 'plans:process-roi',           'label' => 'Plan System ROI'],
            ['command' => 'panels:process-roi',          'label' => 'Panel Investment ROI'],
            ['command' => 'update:crypto',               'label' => 'Crypto Price Update'],
            ['command' => 'update:market',               'label' => 'Market Instruments Update'],
            ['command' => 'copytrade:generate-profits',  'label' => 'Copy Trading Profits'],
            ['command' => 'bot:bulk-trades',              'label' => 'Bot Trading Bulk Trades'],
            ['command' => 'giveaway:select-winners',     'label' => 'Giveaway Winner Selection'],
            ['command' => 'notifications:cleanup',       'label' => 'Notifications Cleanup'],
        ];

        $this->info('========================================');
        $this->info('  Running All Cron Tasks');
        $this->info('  Started at: ' . now()->format('Y-m-d H:i:s'));
        $this->info('========================================');
        $this->newLine();

        foreach ($tasks as $task) {
            $taskStart = microtime(true);
            $this->line("▶ Running: {$task['label']} ({$task['command']})...");

            try {
                $exitCode = Artisan::call($task['command']);
                $output = trim(Artisan::output());
                $duration = round(microtime(true) - $taskStart, 2);

                if ($exitCode === 0) {
                    $this->info("  ✓ Completed in {$duration}s");
                    $results[] = ['task' => $task['label'], 'status' => 'success', 'time' => $duration];
                } else {
                    $this->warn("  ⚠ Finished with exit code {$exitCode} in {$duration}s");
                    $results[] = ['task' => $task['label'], 'status' => 'warning', 'time' => $duration, 'code' => $exitCode];
                }

                if ($output) {
                    // Show first 200 chars of output
                    $this->line("  Output: " . substr($output, 0, 200));
                }
            } catch (\Exception $e) {
                $duration = round(microtime(true) - $taskStart, 2);
                $this->error("  ✗ Failed in {$duration}s: " . $e->getMessage());
                $results[] = ['task' => $task['label'], 'status' => 'error', 'time' => $duration, 'error' => $e->getMessage()];

                Log::error("cron:all - Task '{$task['command']}' failed", [
                    'error' => $e->getMessage(),
                    'trace' => $e->getTraceAsString()
                ]);
            }

            $this->newLine();
        }

        $totalTime = round(microtime(true) - $startTime, 2);
        $success = count(array_filter($results, fn($r) => $r['status'] === 'success'));
        $failed = count(array_filter($results, fn($r) => $r['status'] === 'error'));

        $this->info('========================================');
        $this->info("  All tasks completed in {$totalTime}s");
        $this->info("  Success: {$success} | Failed: {$failed} | Total: " . count($results));
        $this->info('========================================');

        Log::info('cron:all completed', [
            'total_time' => $totalTime,
            'success' => $success,
            'failed' => $failed,
            'results' => $results
        ]);

        return $failed > 0 ? Command::FAILURE : Command::SUCCESS;
    }
}
