<?php

namespace App\Services\Meet;

use App\Models\Room;
use Illuminate\Support\Str;

class StageLayoutService
{
    public function usesStageLayout(Room $room): bool
    {
        return $room->isConference() || $room->isWebinar();
    }

    /** @return array<string, mixed> */
    public function config(Room $room): array
    {
        return [
            'uses_stage_layout' => $this->usesStageLayout($room),
            'panel_discussions' => (bool) $room->setting('panel_discussions', false),
            'stage_layout' => (string) $room->setting('stage_layout', 'plenary'),
            'panels' => array_values((array) $room->setting('panels', [])),
            'active_panel_id' => $room->setting('active_panel_id'),
            'spotlight_speaker_ref' => $room->setting('spotlight_speaker_ref'),
        ];
    }

    /**
     * @param  array<string, mixed>  $data
     */
    public function update(Room $room, array $data): Room
    {
        abort_unless($this->usesStageLayout($room), 422);

        $settings = $room->settings ?? [];

        if (array_key_exists('panel_discussions', $data)) {
            $settings['panel_discussions'] = (bool) $data['panel_discussions'];
        }

        if (array_key_exists('stage_layout', $data)) {
            $layout = (string) $data['stage_layout'];
            abort_unless(in_array($layout, ['plenary', 'panel'], true), 422);
            $settings['stage_layout'] = $layout;

            if ($layout === 'panel') {
                $settings['panel_discussions'] = true;
            }
        }

        if (array_key_exists('active_panel_id', $data)) {
            $settings['active_panel_id'] = $data['active_panel_id'] ?: null;
        }

        if (array_key_exists('spotlight_speaker_ref', $data)) {
            $settings['spotlight_speaker_ref'] = $data['spotlight_speaker_ref'] ?: null;
        }

        if (array_key_exists('panels', $data)) {
            $settings['panels'] = $this->normalizePanels((array) $data['panels']);
        }

        $room->update(['settings' => $settings]);

        return $room->fresh();
    }

    /**
     * @param  array<int, array<string, mixed>>  $panels
     * @return list<array{id: string, name: string, speaker_refs: list<string>}>
     */
    public function normalizePanels(array $panels): array
    {
        return collect($panels)
            ->map(function ($panel) {
                $id = trim((string) ($panel['id'] ?? ''));
                $name = trim((string) ($panel['name'] ?? ''));

                if ($id === '') {
                    $id = 'panel-'.Str::lower(Str::random(8));
                }

                if ($name === '') {
                    return null;
                }

                $speakerRefs = collect($panel['speaker_refs'] ?? [])
                    ->filter(fn ($ref) => is_string($ref) && $ref !== '')
                    ->unique()
                    ->values()
                    ->all();

                return [
                    'id' => $id,
                    'name' => Str::limit($name, 100, ''),
                    'speaker_refs' => $speakerRefs,
                ];
            })
            ->filter()
            ->values()
            ->all();
    }
}
