<?php

declare(strict_types=1);

namespace App\Application\Api;

use App\Framework\Attributes\Route;
use App\Framework\Http\Method;
use App\Framework\Http\Status;
use App\Framework\OpenApi\Attributes\ApiEndpoint;
use App\Framework\OpenApi\Attributes\ApiParameter;
use App\Framework\OpenApi\Attributes\ApiRequestBody;
use App\Framework\OpenApi\Attributes\ApiResponse;
use App\Framework\OpenApi\Attributes\ApiSecurity;
use App\Framework\Router\ApiRoutes;
use App\Framework\Router\Result\JsonResult;

/**
 * Example API controller demonstrating OpenAPI documentation
 */
#[ApiSecurity('bearerAuth')]
final readonly class ExampleApiController
{
    #[Route(path: '/api/users', method: Method::GET, name: ApiRoutes::USERS_LIST)]
    #[ApiEndpoint(
        summary: 'List all users',
        description: 'Retrieve a paginated list of all users in the system',
        tags: ['Users'],
    )]
    #[ApiParameter(
        name: 'page',
        in: 'query',
        description: 'Page number for pagination',
        required: false,
        type: 'integer',
        example: 1,
    )]
    #[ApiParameter(
        name: 'limit',
        in: 'query',
        description: 'Number of items per page',
        required: false,
        type: 'integer',
        example: 20,
    )]
    #[ApiParameter(
        name: 'search',
        in: 'query',
        description: 'Search term to filter users',
        required: false,
        type: 'string',
        example: 'john',
    )]
    #[ApiResponse(
        statusCode: 200,
        description: 'List of users retrieved successfully',
        example: [
            'data' => [
                [
                    'id' => 1,
                    'name' => 'John Doe',
                    'email' => 'john@example.com',
                    'created_at' => '2024-01-01T00:00:00Z',
                ],
            ],
            'pagination' => [
                'current_page' => 1,
                'total_pages' => 5,
                'total_items' => 100,
            ],
        ],
    )]
    #[ApiResponse(
        statusCode: 401,
        description: 'Unauthorized - Invalid or missing authentication token',
    )]
    public function listUsers(): JsonResult
    {
        // Mock data for demonstration
        return new JsonResult([
            'data' => [
                [
                    'id' => 1,
                    'name' => 'John Doe',
                    'email' => 'john@example.com',
                    'created_at' => '2024-01-01T00:00:00Z',
                ],
                [
                    'id' => 2,
                    'name' => 'Jane Smith',
                    'email' => 'jane@example.com',
                    'created_at' => '2024-01-02T00:00:00Z',
                ],
            ],
            'pagination' => [
                'current_page' => 1,
                'total_pages' => 1,
                'total_items' => 2,
            ],
        ]);
    }

    #[Route(path: '/api/users/{id}', method: Method::GET, name: ApiRoutes::USERS_SHOW)]
    #[ApiEndpoint(
        summary: 'Get user by ID',
        description: 'Retrieve detailed information about a specific user',
        tags: ['Users'],
    )]
    #[ApiParameter(
        name: 'id',
        in: 'path',
        description: 'User ID',
        required: true,
        type: 'integer',
        example: 1,
    )]
    #[ApiResponse(
        statusCode: 200,
        description: 'User details retrieved successfully',
        example: [
            'id' => 1,
            'name' => 'John Doe',
            'email' => 'john@example.com',
            'bio' => 'Software developer',
            'created_at' => '2024-01-01T00:00:00Z',
            'updated_at' => '2024-01-01T00:00:00Z',
        ],
    )]
    #[ApiResponse(
        statusCode: 404,
        description: 'User not found',
    )]
    public function showUser(int $id): JsonResult
    {
        if ($id === 1) {
            return new JsonResult([
                'id' => 1,
                'name' => 'John Doe',
                'email' => 'john@example.com',
                'bio' => 'Software developer',
                'created_at' => '2024-01-01T00:00:00Z',
                'updated_at' => '2024-01-01T00:00:00Z',
            ]);
        }

        return new JsonResult(['error' => 'User not found'], Status::NOT_FOUND);
    }

    #[Route(path: '/api/users', method: Method::POST, name: ApiRoutes::USERS_CREATE)]
    #[ApiEndpoint(
        summary: 'Create a new user',
        description: 'Create a new user account in the system',
        tags: ['Users'],
    )]
    #[ApiRequestBody(
        description: 'User data for creation',
        required: true,
        example: [
            'name' => 'John Doe',
            'email' => 'john@example.com',
            'password' => 'secure_password',
        ],
    )]
    #[ApiResponse(
        statusCode: 201,
        description: 'User created successfully',
        example: [
            'id' => 3,
            'name' => 'John Doe',
            'email' => 'john@example.com',
            'created_at' => '2024-01-01T00:00:00Z',
        ],
    )]
    #[ApiResponse(
        statusCode: 400,
        description: 'Validation error - Invalid input data',
    )]
    #[ApiResponse(
        statusCode: 409,
        description: 'Conflict - Email already exists',
    )]
    public function createUser(): JsonResult
    {
        // Mock creation for demonstration
        return new JsonResult([
            'id' => 3,
            'name' => 'New User',
            'email' => 'new@example.com',
            'created_at' => date('c'),
        ], Status::CREATED);
    }

    #[Route(path: '/api/health', method: Method::GET, name: ApiRoutes::HEALTH)]
    #[ApiEndpoint(
        summary: 'Health check',
        description: 'Check the health status of the API',
        tags: ['System'],
    )]
    #[ApiResponse(
        statusCode: 200,
        description: 'API is healthy',
        example: [
            'status' => 'healthy',
            'timestamp' => '2024-01-01T00:00:00Z',
            'version' => '1.0.0',
        ],
    )]
    #[ApiSecurity('apiKey')]
    public function healthCheck(): JsonResult
    {
        return new JsonResult([
            'status' => 'healthy',
            'timestamp' => date('c'),
            'version' => '1.0.0',
        ]);
    }
}
