<?php

namespace App\Http\Controllers\Api\V1\Admin\BetProvider;

use App\Models\BetProvider;
use App\Support\ApiResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;

final class AdminBetProviderController extends Controller
{
    public function index(): JsonResponse
    {
        return ApiResponse::success([
            'items' => BetProvider::query()
                ->orderBy('sort_order')
                ->orderBy('id')
                ->get()
                ->map(fn (BetProvider $provider): array => $this->present($provider))
                ->values()
                ->all(),
        ]);
    }

    public function store(Request $request): JsonResponse
    {
        $data = $request->validate([
            'code' => ['required', 'string', 'max:32', 'regex:/^[A-Za-z0-9_-]+$/', Rule::unique('bet_providers', 'code')],
            'name' => ['required', 'string', 'max:64'],
            'short_code' => ['required', 'string', 'size:1', 'regex:/^[A-Za-z]$/'],
            'is_enabled' => ['sometimes', 'boolean'],
            'sort_order' => ['sometimes', 'integer', 'min:0'],
        ]);

        $provider = BetProvider::query()->create([
            'code' => strtoupper((string) $data['code']),
            'name' => trim((string) $data['name']),
            'short_code' => strtoupper((string) $data['short_code']),
            'is_enabled' => (bool) ($data['is_enabled'] ?? true),
            'sort_order' => (int) ($data['sort_order'] ?? 0),
        ]);

        return ApiResponse::success($this->present($provider));
    }

    public function update(Request $request, BetProvider $betProvider): JsonResponse
    {
        $data = $request->validate([
            'name' => ['sometimes', 'required', 'string', 'max:64'],
            'short_code' => ['sometimes', 'required', 'string', 'size:1', 'regex:/^[A-Za-z]$/'],
            'is_enabled' => ['sometimes', 'boolean'],
            'sort_order' => ['sometimes', 'integer', 'min:0'],
        ]);

        $betProvider->fill(array_filter([
            'name' => isset($data['name']) ? trim((string) $data['name']) : null,
            'short_code' => isset($data['short_code']) ? strtoupper((string) $data['short_code']) : null,
            'is_enabled' => array_key_exists('is_enabled', $data) ? (bool) $data['is_enabled'] : null,
            'sort_order' => array_key_exists('sort_order', $data) ? (int) $data['sort_order'] : null,
        ], static fn (mixed $value): bool => $value !== null))->save();

        $betProvider->refresh();

        return ApiResponse::success($this->present($betProvider));
    }

    private function present(BetProvider $provider): array
    {
        return [
            'id' => (int) $provider->id,
            'code' => $provider->code,
            'name' => $provider->name,
            'short_code' => $provider->short_code ?: strtoupper(substr((string) $provider->code, 0, 1)),
            'is_enabled' => (bool) $provider->is_enabled,
            'sort_order' => (int) $provider->sort_order,
            'is_default' => $provider->code === BetProvider::DEFAULT_CODE,
            'created_at' => $provider->created_at?->toIso8601String(),
            'updated_at' => $provider->updated_at?->toIso8601String(),
        ];
    }
}
