<?php

namespace App\Http\Controllers\Highscore;

use App\Http\Controllers\Controller;
use App\Models\Enums\CharacterClassEnum;
use App\Models\Enums\EmpireEnum;
use App\Models\Game\Highscore\HighscoreCache;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\View\View;

class HighscoreController extends Controller
{
    private const RESULTS_PER_PAGE = 10;
    private const CACHE_LIFETIME_MINUTES = 60; // Refresh every hour

    /**
     * Check if cache needs refresh and refresh if needed
     */
    private function refreshCacheIfNeeded(): void
    {
        $lastEntry = HighscoreCache::first();

        if (!$lastEntry || !$lastEntry->date || $lastEntry->date->diffInMinutes(now()) >= self::CACHE_LIFETIME_MINUTES) {
            Artisan::call('highscore:refresh');
        }
    }

    public function show(Request $request, ?int $empireChoice = null, ?int $classChoice = null, ?int $page = null): View
    {
        $this->refreshCacheIfNeeded();

        $query = HighscoreCache::query()->orderBy('id');

        // If "empireChoice" is a valid empire, add it to the query; otherwise set empireChoice to -1
        if (in_array($empireChoice, array_column(EmpireEnum::cases(), 'value'), true))
            $query->where('empire', $empireChoice);
        else
            $empireChoice = -1;

        // If "classChoice" is a valid character class, add it to the query; otherwise set classChoice to -1
        if (in_array($classChoice, array_column(CharacterClassEnum::cases(), 'value'), true))
            $query->where('job', $classChoice);
        else
            $classChoice = -1;

        // Check whether "characterChoice" was requested
        $validated = $request->validate(['character-choice' => 'nullable']);
        $characterChoice = $validated['character-choice'] ?? null;

        // If "character-choice" was specified, find the character with that name
        if (!empty($characterChoice))
            $query->where('name', 'LIKE', '%' . $characterChoice . '%');

        $highscore = $query->paginate(self::RESULTS_PER_PAGE, ['*'], 'page', $page);

        return view('main/highscore', [
            'highscore' => $highscore,
            'empireChoice' => $empireChoice,
            'classChoice' => $classChoice,
            'characterChoice' => $characterChoice,
        ]);
    }

    public function search(Request $request): View
    {
        $this->refreshCacheIfNeeded();

        $validated = $request->validate([
            'empire-choice' => 'required|int',
            'class-choice' => 'required|int',
            'character-choice' => 'nullable',
        ]);

        $empireChoice = (int) $validated['empire-choice'];
        $classChoice = (int) $validated['class-choice'];
        $characterChoice = $validated['character-choice'];

        $query = HighscoreCache::query()->orderBy('id');

        // If "empire-choice" is a valid empire, add it to the query
        if (in_array($empireChoice, array_column(EmpireEnum::cases(), 'value'), true))
            $query->where('empire', $empireChoice);

        // If "class-choice" is a valid character class, add it to the query
        if (in_array($classChoice, array_column(CharacterClassEnum::cases(), 'value'), true))
            $query->where('job', $classChoice);

        // If "character-choice" was specified, find the character with that name
        if (!empty($characterChoice))
            $query->where('name', 'LIKE', '%' . $characterChoice . '%');

        $highscore = $query->paginate(self::RESULTS_PER_PAGE);

        return view('main/highscore', [
            'highscore' => $highscore,
            'empireChoice' => $empireChoice,
            'classChoice' => $classChoice,
            'characterChoice' => $characterChoice,
        ]);
    }
}
