<?php

declare(strict_types=1);

namespace App\Application\Http\Examples;

use App\Framework\Attributes\Route;
use App\Framework\DateTime\Clock;
use App\Framework\Http\Headers;
use App\Framework\Http\HttpResponse;
use App\Framework\Http\Method;
use App\Framework\Http\Request;
use App\Framework\Http\Status;
use App\Framework\Serializer\Json\JsonSerializer;
use App\Framework\Serializer\Json\JsonSerializerConfig;

/**
 * Example controller for demonstrating batch API functionality
 */
final readonly class BatchExampleController
{
    public function __construct(
        private JsonSerializer $jsonSerializer,
        private Clock $clock
    ) {
    }

    #[Route(path: '/api/examples/users/{id}', method: Method::GET)]
    public function getUser(Request $request): HttpResponse
    {
        $userId = $request->queryParams['id'] ?? '1';

        $user = [
            'id' => (int) $userId,
            'name' => "User {$userId}",
            'email' => "user{$userId}@example.com",
            'created_at' => $this->clock->now()->format('Y-m-d H:i:s'),
        ];

        return new HttpResponse(
            status: Status::OK,
            headers: new Headers(['Content-Type' => 'application/json']),
            body: $this->jsonSerializer->serializeWithConfig($user, JsonSerializerConfig::pretty())
        );
    }

    #[Route(path: '/api/examples/posts', method: Method::POST)]
    public function createPost(Request $request): HttpResponse
    {
        $data = $this->jsonSerializer->deserialize($request->body);

        if (! is_array($data) || empty($data['title'])) {
            return new HttpResponse(
                status: Status::BAD_REQUEST,
                headers: new Headers(['Content-Type' => 'application/json']),
                body: $this->jsonSerializer->serializeWithConfig(['error' => 'Title is required'], JsonSerializerConfig::compact())
            );
        }

        $post = [
            'id' => random_int(1000, 9999),
            'title' => $data['title'],
            'content' => $data['content'] ?? '',
            'author_id' => $data['author_id'] ?? 1,
            'created_at' => $this->clock->now()->format('Y-m-d H:i:s'),
        ];

        return new HttpResponse(
            status: Status::CREATED,
            headers: new Headers(['Content-Type' => 'application/json']),
            body: $this->jsonSerializer->serializeWithConfig($post, JsonSerializerConfig::pretty())
        );
    }

    #[Route(path: '/api/examples/posts/{id}', method: Method::PUT)]
    public function updatePost(Request $request): HttpResponse
    {
        $postId = $request->queryParams['id'] ?? '1';
        $data = $this->jsonSerializer->deserialize($request->body);

        if (! is_array($data)) {
            return new HttpResponse(
                status: Status::BAD_REQUEST,
                headers: new Headers(['Content-Type' => 'application/json']),
                body: $this->jsonSerializer->serializeWithConfig(['error' => 'Invalid JSON data'], JsonSerializerConfig::compact())
            );
        }

        $post = [
            'id' => (int) $postId,
            'title' => $data['title'] ?? "Post {$postId}",
            'content' => $data['content'] ?? '',
            'updated_at' => $this->clock->now()->format('Y-m-d H:i:s'),
        ];

        return new HttpResponse(
            status: Status::OK,
            headers: new Headers(['Content-Type' => 'application/json']),
            body: $this->jsonSerializer->serializeWithConfig($post, JsonSerializerConfig::pretty())
        );
    }

    #[Route(path: '/api/examples/posts/{id}', method: Method::DELETE)]
    public function deletePost(Request $request): HttpResponse
    {
        $postId = $request->queryParams['id'] ?? '1';

        return new HttpResponse(
            status: Status::NO_CONTENT,
            headers: new Headers([]),
            body: ''
        );
    }

    #[Route(path: '/api/examples/slow', method: Method::GET)]
    public function slowEndpoint(Request $request): HttpResponse
    {
        // Simulate slow operation for testing concurrent processing
        $delay = (int) ($request->queryParams['delay'] ?? 1);
        $maxDelay = min($delay, 5); // Maximum 5 seconds
        sleep($maxDelay);

        return new HttpResponse(
            status: Status::OK,
            headers: new Headers(['Content-Type' => 'application/json']),
            body: $this->jsonSerializer->serializeWithConfig([
                'message' => 'Slow operation completed',
                'delay' => $maxDelay,
                'timestamp' => $this->clock->now()->format('Y-m-d H:i:s'),
            ])
        );
    }
}
