<?php

namespace routes;

use classes\bird;
use traits\bird_route_helpers_t;
use traits\route_t;

class birdVoiceCallsRoute
{
    use route_t, bird_route_helpers_t;

    public function run(): void
    {
        // Create a voice call
        $this->post('/bird/voice/calls', function () {
            global $response;
            // Permission: create/place a voice call via Bird
            self::requirePermission('modules_bird_voice_calls_create');
            $client = new bird();
            // Require workspace/channel per Bird API docs
            $ws = $this->normalizeOptionalString($this->fromRequest('workspaceId') ?? $this->fromQuery('workspaceId'));
            $ch = $this->normalizeOptionalString($this->fromRequest('channelId') ?? $this->fromQuery('channelId'));
            if ($ws === '') {
                $ws = $this->getConfiguredWorkspaceId($client);
            }
            if ($ch === '') {
                $ch = $this->getConfiguredChannelId($client);
            }
            if ($ws === '' || $ch === '') {
                $response->error('Missing required parameters: workspaceId, channelId', 400);
            }
            $payload = $this->getParametersAsArray();
            unset($payload['workspaceId'], $payload['channelId']);
            $res = $client->createVoiceCall($ws, $ch, $payload);
            $response->success($res ?? ['status' => 'ok']);
        }, [
            'modules_bird_voice_calls_create' => 'Create/place a voice call via Bird',
        ]);

        // List voice calls (passthrough of query filters)
        $this->get('/bird/voice/calls', function () {
            global $response;
            // Permission: list voice calls via Bird
            self::requirePermission('modules_bird_voice_calls_list');
            $client = new bird();
            $ws = $this->normalizeOptionalString($this->fromRequest('workspaceId') ?? $this->fromQuery('workspaceId'));
            $ch = $this->normalizeOptionalString($this->fromRequest('channelId') ?? $this->fromQuery('channelId'));
            if ($ws === '') {
                $ws = $this->getConfiguredWorkspaceId($client);
            }
            if ($ch === '') {
                $ch = $this->getConfiguredChannelId($client);
            }
            if ($ws === '' || $ch === '') {
                $response->error('Missing required parameters: workspaceId, channelId', 400);
            }
            $query = $this->getParametersAsArray();
            unset($query['workspaceId'], $query['channelId']);
            $res = $client->listVoiceCalls($ws, $ch, $query);
            $response->success($res ?? []);
        }, [
            'modules_bird_voice_calls_list' => 'List voice calls via Bird',
        ]);

        // Get a specific call by ID
        $this->get('/bird/voice/calls/{id}', function () {
            global $response;
            // Permission: get a specific voice call via Bird
            self::requirePermission('modules_bird_voice_calls_get');
            $client = new bird();
            $id = (string)$this->fromRoute('id');
            if ($id === null || $id === '') {
                $response->error('Missing id', 400);
            }
            $ws = $this->normalizeOptionalString($this->fromRequest('workspaceId') ?? $this->fromQuery('workspaceId'));
            $ch = $this->normalizeOptionalString($this->fromRequest('channelId') ?? $this->fromQuery('channelId'));
            if ($ws === '') {
                $ws = $this->getConfiguredWorkspaceId($client);
            }
            if ($ch === '') {
                $ch = $this->getConfiguredChannelId($client);
            }
            if ($ws === '' || $ch === '') {
                $response->error('Missing required parameters: workspaceId, channelId', 400);
            }
            $res = $client->getVoiceCall($ws, $ch, $id);
            $response->success($res ?? []);
        }, [
            'modules_bird_voice_calls_get' => 'Get a voice call by ID via Bird',
        ]);

        // Hang up an active call by ID
        $this->post('/bird/voice/calls/{id}/hangup', function () {
            global $response;
            // Permission: hang up a specific voice call via Bird
            self::requirePermission('modules_bird_voice_calls_hangup');
            $client = new bird();
            $id = (string)$this->fromRoute('id');
            if ($id === null || $id === '') {
                $response->error('Missing id', 400);
            }
            $ws = $this->normalizeOptionalString($this->fromRequest('workspaceId') ?? $this->fromQuery('workspaceId'));
            $ch = $this->normalizeOptionalString($this->fromRequest('channelId') ?? $this->fromQuery('channelId'));
            if ($ws === '') {
                $ws = $this->getConfiguredWorkspaceId($client);
            }
            if ($ch === '') {
                $ch = $this->getConfiguredChannelId($client);
            }
            if ($ws === '' || $ch === '') {
                $response->error('Missing required parameters: workspaceId, channelId', 400);
            }
            $payload = [];
            $cause = $this->normalizeOptionalString($this->fromRequest('cause') ?? $this->fromQuery('cause'));
            if ($cause !== '') {
                $payload['cause'] = $cause;
            }
            $res = $client->hangupVoiceCall($ws, $ch, $id, $payload);
            $response->success($res ?? ['status' => 'ok']);
        }, [
            'modules_bird_voice_calls_hangup' => 'Hang up a voice call by ID via Bird',
        ]);

        // Say a message on an active call and hang up afterwards
        $this->post('/bird/voice/calls/{id}/say', function () {
            global $response;
            // Permission: say a message on a voice call via Bird
            self::requirePermission('modules_bird_voice_calls_say');
            $client = new bird();
            $id = (string)$this->fromRoute('id');
            if ($id === null || $id === '') {
                $response->error('Missing id', 400);
            }
            $ws = $this->normalizeOptionalString($this->fromRequest('workspaceId') ?? $this->fromQuery('workspaceId'));
            $ch = $this->normalizeOptionalString($this->fromRequest('channelId') ?? $this->fromQuery('channelId'));
            if ($ws === '') {
                $ws = $this->getConfiguredWorkspaceId($client);
            }
            if ($ch === '') {
                $ch = $this->getConfiguredChannelId($client);
            }
            if ($ws === '' || $ch === '') {
                $response->error('Missing required parameters: workspaceId, channelId', 400);
            }
            $payload = $this->getParametersAsArray();
            unset($payload['workspaceId'], $payload['channelId']);

            // Bird's /say REST API endpoint plays the message.
            // To fulfill the requirement of hanging up afterwards, we should ensure the call is terminated.
            // Many Bird actions support a 'hangup' field in the payload to terminate the call after the action is complete.
            if (!isset($payload['hangup'])) {
                $payload['hangup'] = true;
            }

            $res = $client->sayMessage($ws, $ch, $id, $payload);
            $response->success($res ?? ['status' => 'ok']);
        }, [
            'modules_bird_voice_calls_say' => 'Say a message on a voice call by ID via Bird',
        ]);

        // Gather input on an active call
        $this->post('/bird/voice/calls/{id}/gather', function () {
            global $response;
            // Permission: gather input on a voice call via Bird
            self::requirePermission('modules_bird_voice_calls_gather');
            $client = new bird();
            $id = (string)$this->fromRoute('id');
            if ($id === null || $id === '') {
                $response->error('Missing id', 400);
            }
            $ws = $this->normalizeOptionalString($this->fromRequest('workspaceId') ?? $this->fromQuery('workspaceId'));
            $ch = $this->normalizeOptionalString($this->fromRequest('channelId') ?? $this->fromQuery('channelId'));
            if ($ws === '') {
                $ws = $this->getConfiguredWorkspaceId($client);
            }
            if ($ch === '') {
                $ch = $this->getConfiguredChannelId($client);
            }
            if ($ws === '' || $ch === '') {
                $response->error('Missing required parameters: workspaceId, channelId', 400);
            }
            $payload = $this->getParametersAsArray();
            unset($payload['workspaceId'], $payload['channelId']);

            $res = $client->gatherMessage($ws, $ch, $id, $payload);
            $response->success($res ?? ['status' => 'ok']);
        }, [
            'modules_bird_voice_calls_gather' => 'Gather input on a voice call by ID via Bird',
        ]);

        // Place test outbound call and hang up when accepted
        $this->post('/bird/voice/calls/test-outbound', function () {
            global $response;
            self::requirePermission('modules_bird_voice_calls_test_outbound');
            $client = new bird();

            $ws = $this->normalizeOptionalString($this->fromRequest('workspaceId') ?? $this->fromQuery('workspaceId'));
            $ch = $this->normalizeOptionalString($this->fromRequest('channelId') ?? $this->fromQuery('channelId'));
            if ($ws === '') {
                $ws = $this->getConfiguredWorkspaceId($client);
            }
            if ($ch === '') {
                $ch = $this->getConfiguredChannelId($client);
            }
            if ($ws === '' || $ch === '') {
                $response->error('Missing required parameters: workspaceId, channelId', 400);
            }

            $payload = $this->getParametersAsArray();
            unset($payload['workspaceId'], $payload['channelId']);

            try {
                $result = $client->createOutboundTestCallAndHangupWhenAccepted($ws, $ch, $payload);
                $response->success($result);
            } catch (\Throwable $e) {
                $response->error($e->getMessage(), 500);
            }
        }, [
            'modules_bird_voice_calls_test_outbound' => 'Place a test outbound call and hang up when accepted',
        ]);
    }
}
