<?php

namespace App\Http\Controllers\Web;

use App\Http\Controllers\Controller;
use App\Services\InstallerService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Carbon;

/**
 * Token-protected GET endpoints so a free external pinger (e.g. cron-job.org)
 * can trigger scheduled work on hosts with no cron access at all. Not under
 * 'auth' — protected instead by a per-install shared secret minted at
 * install time and stored only in storage/app/installed.lock (never in a
 * DB column or the .env file).
 */
class TaskController extends Controller
{
    public function purgeSnapshots(Request $request, InstallerService $installer)
    {
        if ($response = $this->rejectUnlessTokenValid($request, $installer)) {
            return $response;
        }

        $days = (int) $request->query('days', 60);
        $days = $days > 0 ? $days : 60;

        Artisan::call('attendance:purge-snapshots', ['--days' => $days]);

        return response()->json(['ok' => true, 'output' => trim(Artisan::output())]);
    }

    public function computeAttendance(Request $request, InstallerService $installer)
    {
        if ($response = $this->rejectUnlessTokenValid($request, $installer)) {
            return $response;
        }

        $date = $request->query('date') ? Carbon::parse($request->query('date')) : Carbon::yesterday();

        Artisan::call('attendance:compute', ['--date' => $date->toDateString()]);

        return response()->json(['ok' => true, 'date' => $date->toDateString(), 'output' => trim(Artisan::output())]);
    }

    protected function rejectUnlessTokenValid(Request $request, InstallerService $installer)
    {
        $lock = $installer->lockData();
        $expected = $lock['tasks_token'] ?? null;
        $given = (string) $request->query('token', '');

        if (! $expected || $given === '' || ! hash_equals($expected, $given)) {
            return response()->json(['error' => ['code' => 'invalid_token', 'message' => 'Missing or invalid task token.']], 401);
        }

        return null;
    }
}
