<?php

declare(strict_types=1);

namespace App\Application\FeatureFlags;

use App\Framework\Attributes\Route;
use App\Framework\FeatureFlags\FeatureFlag;
use App\Framework\FeatureFlags\FeatureFlagManager;
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;

/**
 * Controller for managing feature flags
 */
final readonly class FeatureFlagController
{
    public function __construct(
        private FeatureFlagManager $flagManager
    ) {
    }

    #[Route(path: '/admin/feature-flags', method: Method::GET)]
    public function index(Request $request): HttpResponse
    {
        $flags = $this->flagManager->getAllFlags();
        $summary = $this->flagManager->getStatusSummary();

        $response = [
            'flags' => array_map(fn ($flag) => $this->flagToArray($flag), $flags),
            'summary' => $summary,
        ];

        return new HttpResponse(
            status: Status::OK,
            headers: new Headers(['Content-Type' => 'application/json']),
            body: json_encode($response, JSON_PRETTY_PRINT) ?: '{}'
        );
    }

    #[Route(path: '/admin/feature-flags/{name}', method: Method::GET)]
    public function show(Request $request): HttpResponse
    {
        $name = $request->queryParams['name'] ?? '';

        $flag = $this->flagManager->getFlag($name);
        if ($flag === null) {
            return new HttpResponse(
                status: Status::NOT_FOUND,
                headers: new Headers(['Content-Type' => 'application/json']),
                body: json_encode(['error' => 'Feature flag not found']) ?: '{}'
            );
        }

        return new HttpResponse(
            status: Status::OK,
            headers: new Headers(['Content-Type' => 'application/json']),
            body: json_encode($this->flagToArray($flag), JSON_PRETTY_PRINT) ?: '{}'
        );
    }

    #[Route(path: '/admin/feature-flags/{name}/enable', method: Method::POST)]
    public function enable(Request $request): HttpResponse
    {
        $name = $request->queryParams['name'] ?? '';

        $this->flagManager->enable($name, 'Enabled via API');

        return new HttpResponse(
            status: Status::OK,
            headers: new Headers(['Content-Type' => 'application/json']),
            body: json_encode(['message' => "Feature flag '{$name}' enabled"]) ?: '{}'
        );
    }

    #[Route(path: '/admin/feature-flags/{name}/disable', method: Method::POST)]
    public function disable(Request $request): HttpResponse
    {
        $name = $request->queryParams['name'] ?? '';

        $this->flagManager->disable($name);

        return new HttpResponse(
            status: Status::OK,
            headers: new Headers(['Content-Type' => 'application/json']),
            body: json_encode(['message' => "Feature flag '{$name}' disabled"]) ?: '{}'
        );
    }

    #[Route(path: '/admin/feature-flags/{name}/percentage', method: Method::POST)]
    public function setPercentage(Request $request): HttpResponse
    {
        $name = $request->queryParams['name'] ?? '';

        $body = json_decode($request->body, true);
        $percentage = (int) ($body['percentage'] ?? 0);

        if ($percentage < 0 || $percentage > 100) {
            return new HttpResponse(
                status: Status::BAD_REQUEST,
                headers: new Headers(['Content-Type' => 'application/json']),
                body: json_encode(['error' => 'Percentage must be between 0 and 100']) ?: '{}'
            );
        }

        $this->flagManager->setPercentageRollout(
            $name,
            $percentage,
            "Set to {$percentage}% rollout via API"
        );

        return new HttpResponse(
            status: Status::OK,
            headers: new Headers(['Content-Type' => 'application/json']),
            body: json_encode(['message' => "Feature flag '{$name}' set to {$percentage}% rollout"]) ?: '{}'
        );
    }

    #[Route(path: '/admin/feature-flags/{name}', method: Method::DELETE)]
    public function delete(Request $request): HttpResponse
    {
        $name = $request->queryParams['name'] ?? '';

        if (! $this->flagManager->exists($name)) {
            return new HttpResponse(
                status: Status::NOT_FOUND,
                headers: new Headers(['Content-Type' => 'application/json']),
                body: json_encode(['error' => 'Feature flag not found']) ?: '{}'
            );
        }

        $this->flagManager->deleteFlag($name);

        return new HttpResponse(
            status: Status::OK,
            headers: new Headers(['Content-Type' => 'application/json']),
            body: json_encode(['message' => "Feature flag '{$name}' deleted"]) ?: '{}'
        );
    }

    /**
     * @return array<string, mixed>
     */
    private function flagToArray(FeatureFlag $flag): array
    {
        return [
            'name' => $flag->name,
            'status' => $flag->status->value,
            'description' => $flag->description,
            'conditions' => $flag->conditions,
            'enabled_at' => $flag->enabledAt?->toIso8601(),
            'expires_at' => $flag->expiresAt?->toIso8601(),
            'is_enabled' => $flag->isEnabled(),
        ];
    }
}
