<?php

namespace App\Http\Controllers;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;

class CronExecutionController extends Controller
{
    /**
     * Allowed scheduled Artisan commands callable through the cron runner.
     *
     * @var array<string>
     */
    public const ALLOWED_COMMANDS = [
        'schedule:run',
        'campaigns:sync-performance',
        'platforms:refresh-tokens',
        'queue:prune-failed',
        'queue:prune-batches',
    ];

    /**
     * Handle incoming cron execution request.
     */
    public function __invoke(Request $request): JsonResponse
    {
        // If CRON_TOKEN is set in environment, enforce strict token validation.
        // If not set, access is governed by network/VPC perimeter (matching legacy adcenter/advertisers).
        $configuredToken = config('app.cron_token');
        if (! empty($configuredToken)) {
            $providedToken = $request->header('X-Cron-Token') ?: $request->input('token');
            if (! hash_equals((string) $configuredToken, (string) $providedToken)) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Unauthorized: Invalid cron token',
                ], 401);
            }
        }

        $command = (string) $request->input('command', 'schedule:run');

        if (! in_array($command, self::ALLOWED_COMMANDS, true)) {
            return response()->json([
                'status' => 'error',
                'message' => 'Command not allowed',
                'allowed_commands' => self::ALLOWED_COMMANDS,
            ], 400);
        }

        @set_time_limit(300);

        $exitCode = Artisan::call($command);
        $output = trim(Artisan::output());

        return response()->json([
            'status' => $exitCode === 0 ? 'success' : 'failed',
            'command' => $command,
            'exit_code' => $exitCode,
            'output' => $output,
        ]);
    }
}
