<?php

namespace App\Http\Controllers;

use App\Http\Requests\UpdateMeRequest;
use App\Http\Resources\UserTypeResource;
use App\Services\UserService;
use App\Http\Requests\UserRequest;
use App\Http\Resources\UserResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class UserController extends Controller
{
    public function __construct(protected UserService $service) {}

    public function index(): JsonResponse
    {
        $items = $this->service->getAll();

        return $this->successResponse(
            payload: UserResource::collection($items),
        );
    }

    public function store(UserRequest $request): JsonResponse
    {
        $item = $this->service->create($request->validated());

        return $this->successResponse(
            payload: new UserResource($item),
            message: __("messages.created"),
            code:    201,
        );
    }

    public function show(int $id): JsonResponse
    {
        $item = $this->service->findById($id);

        return $this->successResponse(payload: new UserResource($item));
    }

    public function update(UserRequest $request, int $id): JsonResponse
    {
        $item = $this->service->update($id, $request->validated());

        return $this->successResponse(
            payload: new UserResource($item),
            message: __("messages.updated"),
        );
    }

    public function destroy(int $id): JsonResponse
    {
        $this->service->delete($id);

        return $this->successResponse(
            message: __('messages.deleted'),
            code:    204,
        );
    }

    //

    public function getUserTypes(): JsonResponse
    {
        $user_types = $this->service->getUserTypes();

        return $this->successResponse(
            payload: new UserTypeResource($user_types),
        );
    }

    public function me(): JsonResponse
    {
        $user = $this->service->me();

        return $this->successResponse(payload: new UserResource($user));
    }

    public function updateMe(UpdateMeRequest $request): JsonResponse
    {
        $traceId = Str::uuid()->toString();

        Log::withContext(['trace_id' => $traceId]);

        $hasAvatar = $request->hasFile('avatar');
        $avatar    = $request->file('avatar');

        $data       = $request->validated();
        $hasBase64  = ! empty(data_get($data, 'avatar_base64'));

        Log::warning('[avatar-upload] Requisição recebida em updateMe', [
            'user_id'           => auth()->id(),
            'has_avatar'        => $hasAvatar,
            'has_avatar_base64' => $hasBase64,
            'avatar_base64_len' => $hasBase64 ? strlen(data_get($data, 'avatar_base64')) : null,
            'avatar_valid'      => $hasAvatar ? $avatar->isValid()                       : null,
            'avatar_size'       => $hasAvatar ? $avatar->getSize()                       : null,
            'avatar_mime'       => $hasAvatar ? $avatar->getMimeType()                   : null,
            'avatar_extension'  => $hasAvatar ? $avatar->getClientOriginalExtension()    : null,
            'avatar_error'      => $hasAvatar ? $avatar->getError()                      : null,
            'method'            => $request->method(),
            'content_type'      => $request->header('Content-Type'),
        ]);

        if ($hasBase64) {
            $decoded = $this->decodeBase64ToUploadedFile(data_get($data, 'avatar_base64'));

            Log::warning('[avatar-upload] Avatar base64 decodificado', [
                'decode_ok'    => $decoded !== null,
                'decoded_size' => $decoded?->getSize(),
                'decoded_mime' => $decoded?->getClientMimeType(),
            ]);

            if ($decoded) {
                $data['avatar'] = $decoded;
            }
        }

        unset($data['avatar_base64']);

        $user = $this->service->updateMe($data);

        Log::warning('[avatar-upload] updateMe concluído com sucesso', [
            'user_id'          => $user->id,
            'client_id'        => $user->client?->id,
            'profile_media_id' => $user->client?->profile_media_id,
            'media_path'       => $user->client?->profileMedia?->path,
            'media_url'        => $user->client?->profileMedia?->url,
        ]);

        return $this->successResponse(
            payload: new UserResource($user),
            message: __('messages.updated'),
        );
    }

    //

    private function decodeBase64ToUploadedFile(string $base64): ?UploadedFile
    {
        if (preg_match('/^data:(image\/[a-zA-Z0-9.+-]+);base64,(.+)$/s', $base64, $matches)) {
            $mime    = data_get($matches, 1);
            $content = base64_decode(data_get($matches, 2), true);
        } else {
            $mime    = 'image/jpeg';
            $content = base64_decode($base64, true);
        }

        if ($content === false || $content === '') {
            return null;
        }

        $extension = match ($mime) {
            'image/png'               => 'png',
            'image/webp'              => 'webp',
            'image/jpg', 'image/jpeg' => 'jpg',
            default                   => 'jpg',
        };

        $tmpPath = tempnam(sys_get_temp_dir(), 'avatar_');

        if ($tmpPath === false || file_put_contents($tmpPath, $content) === false) {
            return null;
        }

        $originalName = 'avatar.'.$extension;

        return new UploadedFile(
            path:         $tmpPath,
            originalName: $originalName,
            mimeType:     $mime,
            test:         true,
        );
    }
}
