<?php

namespace traits;

require_once WD . '/classes/bird.php';
require_once WD . '/modules/bird/helpers/bird_request_validator.php';

use bird\helpers\bird_request_validator;
use classes\bird;

trait bird_route_validation_t
{
    private function birdFailValidation(string|array $errors): void
    {
        global $response;

        $normalizedErrors = [];
        if (is_array($errors)) {
            foreach ($errors as $error) {
                if (!is_string($error)) {
                    continue;
                }
                $trimmed = trim($error);
                if ($trimmed !== '') {
                    $normalizedErrors[] = $trimmed;
                }
            }
        } else {
            $trimmed = trim($errors);
            if ($trimmed !== '') {
                $normalizedErrors[] = $trimmed;
            }
        }

        if ($normalizedErrors === []) {
            $normalizedErrors[] = 'Validation failed';
        }

        $response->error([
            'message' => 'Validation failed',
            'errors' => array_values(array_unique($normalizedErrors)),
        ], 400);
    }

    private function birdAssertUuid(string $value, string $field): string
    {
        $normalized = trim($value);
        if ($normalized === '') {
            $this->birdFailValidation($field . ' is required');
        }
        if (!bird_request_validator::isUuid($normalized)) {
            $this->birdFailValidation($field . ' must be a UUID');
        }
        return $normalized;
    }

    private function birdResolveWorkspaceId(bird $client): string
    {
        $workspaceId = $this->normalizeOptionalString($this->fromRequest('workspaceId') ?? $this->fromQuery('workspaceId'));
        if ($workspaceId === '') {
            $workspaceId = $this->getConfiguredWorkspaceId($client);
        }
        if ($workspaceId === '') {
            $this->birdFailValidation('Missing required parameter: workspaceId');
        }
        return $this->birdAssertUuid($workspaceId, 'workspaceId');
    }

    private function birdResolveWorkspaceAndChannelIds(bird $client): array
    {
        $workspaceId = $this->normalizeOptionalString($this->fromRequest('workspaceId') ?? $this->fromQuery('workspaceId'));
        $channelId = $this->normalizeOptionalString($this->fromRequest('channelId') ?? $this->fromQuery('channelId'));

        if ($workspaceId === '') {
            $workspaceId = $this->getConfiguredWorkspaceId($client);
        }
        if ($channelId === '') {
            $channelId = $this->getConfiguredChannelId($client);
        }
        if ($workspaceId === '' || $channelId === '') {
            $this->birdFailValidation('Missing required parameters: workspaceId, channelId');
        }

        return [
            $this->birdAssertUuid($workspaceId, 'workspaceId'),
            $this->birdAssertUuid($channelId, 'channelId'),
        ];
    }

    private function birdResolveRouteCallId(string $key = 'id'): string
    {
        $callId = $this->normalizeOptionalString((string)$this->fromRoute($key));
        if ($callId === '') {
            $this->birdFailValidation('Missing required parameter: callId');
        }
        return $this->birdAssertUuid($callId, 'callId');
    }

    private function birdResolveRouteRecordingId(string $key = 'recordingId'): string
    {
        $recordingId = $this->normalizeOptionalString((string)$this->fromRoute($key));
        if ($recordingId === '') {
            $this->birdFailValidation('Missing required parameter: recordingId');
        }
        return $this->birdAssertUuid($recordingId, 'recordingId');
    }

    private function birdPayloadWithout(array $keys): array
    {
        $payload = $this->getParametersAsArray();
        foreach ($keys as $key) {
            unset($payload[$key]);
        }
        return $payload;
    }

    private function birdNormalizeCsvField(array $payload, string $key): array
    {
        if (!array_key_exists($key, $payload)) {
            return $payload;
        }
        $value = $payload[$key];
        if (is_string($value)) {
            $parts = array_map('trim', explode(',', $value));
            $payload[$key] = array_values(array_filter($parts, static fn($part) => $part !== ''));
            return $payload;
        }
        if (is_array($value)) {
            $payload[$key] = array_values(array_filter(array_map(static fn($part) => is_scalar($part) ? trim((string)$part) : '', $value), static fn($part) => $part !== ''));
            return $payload;
        }
        return $payload;
    }

    private function birdValidateSchema(array $payload, array $schema): array
    {
        $errors = bird_request_validator::validate($payload, $schema);
        if ($errors !== []) {
            $this->birdFailValidation($errors);
        }
        return $payload;
    }
}
