<?php

namespace App\Http\Controllers;

use App\Enums\RoleName;
use App\Models\EarnApiToken;
use App\Models\EarnTaskAssignment;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use RuntimeException;

/**
 * Kodular istemcisine cihazla eşleştirilmiş JSON görev akışı sağlar.
 *
 * @author Gökhan Engin - İletişim : https://bit.ly/YazılımUzmanı
 */
class TestTaskController extends Controller
{
    /**
     * Yapılandırılmış görevleri gerçek müşteri sahibiyle doğrulayıp token ve cihaza tekil olarak atar.
     *
     * @author Gökhan Engin - İletişim : https://bit.ly/YazılımUzmanı
     */
    public function index(Request $request): JsonResponse
    {
        $allowedHosts = config('test_tasks.allowed_hosts', []);
        $tasks = config('test_tasks.tasks', []);
        $customerEmail = config('test_tasks.customer_email');
        $token = $request->attributes->get('earn_api_token');
        $deviceHash = $request->attributes->get('earn_device_hash');

        if (! $token instanceof EarnApiToken || ! is_string($deviceHash) || ! is_string($customerEmail)) {
            throw new RuntimeException('Test task ownership is not configured.');
        }

        $customer = User::query()->where('email', $customerEmail)->first();
        if (! $customer?->hasRole(RoleName::Customer)) {
            throw new RuntimeException('Test task customer is invalid.');
        }

        $payload = [];
        foreach ($tasks as $task) {
            $url = $task['url'] ?? null;

            if (! is_string($url) || parse_url($url, PHP_URL_SCHEME) !== 'https' || ! in_array(parse_url($url, PHP_URL_HOST), $allowedHosts, true)) {
                throw new RuntimeException('Test task configuration contains a URL outside the HTTPS allowlist.');
            }

            // Görevi ilk istemciye atomik olarak kilitler.
            // Yazar: Gökhan Engin - İletişim : https://bit.ly/YazılımUzmanı
            $assignment = DB::transaction(function () use ($task, $customer, $token, $deviceHash): EarnTaskAssignment {
                return EarnTaskAssignment::query()->lockForUpdate()->firstOrCreate(
                    ['task_id' => $task['task_id']],
                    ['user_id' => $customer->id, 'earn_member_id' => $token->tokenable_id,
                        'personal_access_token_id' => $token->id, 'device_id_hash' => $deviceHash,
                        'url' => $task['url'], 'duration_seconds' => $task['duration_seconds'], 'assigned_at' => now()],
                );
            }, 3);

            if ($assignment->personal_access_token_id !== $token->id
                || ! hash_equals($assignment->device_id_hash, $deviceHash)
                || $assignment->result()->exists()) {
                continue;
            }

            $payload[] = ['CID' => $assignment->user_id, 'task_id' => $assignment->task_id,
                'url' => $assignment->url, 'duration_seconds' => $assignment->duration_seconds,
                'completed' => false, 'responseCode' => null, 'error' => null];
        }

        return response()
            ->json(['tasks' => $payload])
            ->header('Cache-Control', 'no-store');
    }
}
