<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Models\PointLog;
use App\Models\PointRule;
use App\Models\User;
use App\Services\PointService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class PointController extends Controller
{
    public function __construct(private PointService $points)
    {
    }

    public function me(Request $request): JsonResponse
    {
        $user = $request->user();
        if (!$user) {
            return response()->json(['message' => 'Unauthenticated'], 401);
        }
        return response()->json([
            'data' => [
                'balance' => $this->points->balance($user),
                'level' => (int) $user->level,
            ],
        ]);
    }

    public function myLogs(Request $request): JsonResponse
    {
        $user = $request->user();
        if (!$user) {
            return response()->json(['message' => 'Unauthenticated'], 401);
        }
        $perPage = min(100, (int) $request->query('per_page', 20));
        $logs = PointLog::query()
            ->where('user_id', $user->id)
            ->orderByDesc('created_at')
            ->paginate($perPage);
        return response()->json($logs);
    }

    public function rules(): JsonResponse
    {
        $rules = PointRule::query()->where('is_active', true)->get();
        return response()->json(['data' => $rules]);
    }

    public function adminAdjust(Request $request, string $userId): JsonResponse
    {
        $data = $request->validate([
            'amount' => 'required|integer',
            'reason' => 'required|string|max:100',
        ]);
        /** @var User $user */
        $user = User::query()->findOrFail($userId);
        $log = $this->points->adminAdjust($user, $data['amount'], $data['reason']);
        return response()->json(['data' => $log]);
    }

    public function adminUpdateRules(Request $request): JsonResponse
    {
        $payload = $request->validate([
            'rules' => 'required|array|min:1',
            'rules.*.action' => 'required|string|max:50',
            'rules.*.points' => 'required|integer',
            'rules.*.cap_per_day' => 'nullable|integer|min:0',
            'rules.*.is_active' => 'nullable|boolean',
        ]);
        foreach ($payload['rules'] as $row) {
            PointRule::query()->updateOrCreate(
                ['action' => $row['action']],
                [
                    'points' => $row['points'],
                    'cap_per_day' => $row['cap_per_day'] ?? null,
                    'is_active' => $row['is_active'] ?? true,
                ],
            );
        }
        return response()->json(['data' => PointRule::query()->get()]);
    }
}
