<?php

namespace EasyLinkAutomations\HTTP\Controllers\Actions;

if (!defined('ABSPATH')) {
    exit;
}

use EasyLinkAutomations\Actions\MicrosoftTeams\MicrosoftTeamsRequestHelper;
use EasyLinkAutomations\HTTP\Request\Request;
use EasyLinkAutomations\HTTP\Response;

final class MicrosoftTeamsController
{
    public function teams(Request $request): Response
    {
        return $this->options($request, '/v1.0/me/joinedTeams', 'teams', 'displayName');
    }

    public function channels(Request $request): Response
    {
        $teamId = $this->required($request, 'team_id', 'Team');
        if ($teamId instanceof Response) {
            return $teamId;
        }

        return $this->options(
            $request,
            '/v1.0/teams/' . MicrosoftTeamsRequestHelper::id($teamId) . '/channels',
            'channels',
            'displayName'
        );
    }

    public function chats(Request $request): Response
    {
        return $this->options($request, '/v1.0/me/chats', 'chats', 'topic', ['$expand' => 'members'], true);
    }

    public function plans(Request $request): Response
    {
        $groupId = $this->required($request, 'group_id', 'Team');
        if ($groupId instanceof Response) {
            return $groupId;
        }

        return $this->options(
            $request,
            '/v1.0/groups/' . MicrosoftTeamsRequestHelper::id($groupId) . '/planner/plans',
            'plans',
            'title'
        );
    }

    public function buckets(Request $request): Response
    {
        $planId = $this->required($request, 'plan_id', 'Plan');
        if ($planId instanceof Response) {
            return $planId;
        }

        return $this->options(
            $request,
            '/v1.0/planner/plans/' . MicrosoftTeamsRequestHelper::id($planId) . '/buckets',
            'buckets',
            'name'
        );
    }

    public function members(Request $request): Response
    {
        $groupId = $this->required($request, 'group_id', 'Team');
        if ($groupId instanceof Response) {
            return $groupId;
        }

        return $this->options(
            $request,
            '/v1.0/groups/' . MicrosoftTeamsRequestHelper::id($groupId) . '/members',
            'members',
            'displayName'
        );
    }

    private function options(
        Request $request,
        string $path,
        string $key,
        string $labelField,
        array $query = [],
        bool $chatLabels = false
    ): Response {
        $connectionId = (int) $request->get('connection_id');
        if (!$connectionId) {
            return Response::error('Connection ID is required', 400);
        }

        $result = MicrosoftTeamsRequestHelper::listAll($connectionId, $path, $query, 500);
        if (!$result['success']) {
            return Response::error($result['message'], 400);
        }

        $items = [];
        foreach (is_array($result['data']) ? $result['data'] : [] as $record) {
            $id = trim((string) ($record['id'] ?? ''));
            if ($id === '') {
                continue;
            }
            $label = trim((string) ($record[$labelField] ?? ''));
            if ($chatLabels && $label === '') {
                $members = [];
                foreach (is_array($record['members'] ?? null) ? $record['members'] : [] as $member) {
                    if (!empty($member['displayName'])) {
                        $members[] = (string) $member['displayName'];
                    }
                }
                $label = implode(', ', $members);
            }
            if ($chatLabels) {
                $label = ($label !== '' ? $label : 'Untitled chat') . ' (' . ($record['chatType'] ?? 'chat') . ')';
            }
            $items[] = ['value' => $id, 'label' => $label !== '' ? $label : $key . ' #' . $id];
        }

        return Response::success([$key => $items]);
    }

    private function required(Request $request, string $key, string $label): string|Response
    {
        $value = trim((string) $request->get($key));
        if ($value === '') {
            return Response::error($label . ' is required', 400);
        }

        return $value;
    }
}
