<?php

namespace App\Master\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Master\ApiUserRepository;
use App\Master\Http\Resources\ApiUserList;
use App\Master\Http\Resources\ApiUserView;
use App\Master\Models\ApiToken;
use App\Master\Models\ApiUser;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Http\Response;

class ApiUserController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        $term = $request->input('term');

        $users = ApiUser::query()
            ->when(
                $request->filled('term'),
                fn ($query) => $query->where('name', 'like', "%$term%")
            )
            ->when(
                $request->filled('tenant'),
                fn ($query) => $query->whereHas(
                    'tenants',
                    fn ($tenantQuery) => $tenantQuery->whereKey($request->input('tenant'))
                )
            )
            ->with(['tenants', 'tokens'])
            ->paginate();

        $users->getCollection()->each(function (ApiUser $user): void {
            $user->append(['credential_expires_at', 'credential_expires_in_days'])
                ->makeHidden([
                    'client_id',
                    'client_secret',
                    'previous_client_id',
                    'previous_client_secret',
                    'previous_credentials_expires_at',
                ]);
        });

        return new ApiUserList($users);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required|string',
        ]);

        $user = ApiUser::query()->create([
            'name' => $request->input('name'),
        ]);

        return new ApiUserView($user);
    }

    /**
     * Display the specified resource.
     */
    public function show(ApiUser $apiUser)
    {
        return new ApiUserView($apiUser);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, ApiUser $apiUser, ApiUserRepository $repository)
    {
        $repository->update($apiUser, $request->input());
        return new ApiUserView($apiUser->refresh());
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(ApiUser $apiUser): Response
    {
        $apiUser->tokens()->delete();
        $apiUser->delete();
        return response('ok');
    }

    public function createCredentials(ApiUser $apiUser, ApiUserRepository $repository)
    {
        $repository->createAuthCredentials($apiUser);
        return new ApiUserView($apiUser);
    }

    public function expireToken(ApiUser $apiUser, ApiToken $token, ApiUserRepository $repository)
    {
        if ($token->api_user_id !== $apiUser->id) {
            return response('Forbidden', 401);
        }

        $repository->expireToken($token);
        return new ApiUserView($apiUser);
    }

    public function usage(ApiUser $apiUser): array
    {
        $usage_data = $apiUser->apiUsage()
            ->where('time_window', '>=', Carbon::now()->subMonth())
            ->get()
            ->groupBy('time_window')
            ->map(fn ($group) => $group->sum('hits'));

        return [
            'labels' => $usage_data->keys(),
            'datasets' => [
                [
                    'label' => 'API Hits',
                    'backgroundColor' => '#600000',
                    'data' => $usage_data,
                    'tension' => 0.5
                ],
            ],
        ];
    }
}
