<?php

namespace EasyLinkAutomations\HTTP\Controllers\Actions;

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

use EasyLinkAutomations\Actions\CleverReach\CleverReachReceiverHelper;
use EasyLinkAutomations\Actions\CleverReach\CleverReachRequestHelper;
use EasyLinkAutomations\HTTP\Request\Request;
use EasyLinkAutomations\HTTP\Response;

/**
 * Remote option sources for CleverReach action configuration.
 *
 * Lives in the free tier because the free subscriber actions depend on it;
 * the pro actions reuse the same routes rather than duplicating them.
 */
final class CleverReachController
{
    /**
     * Receiver groups (lists) available on the account.
     */
    public function groups(Request $request): Response
    {
        $connectionId = (int) $request->get('connection_id');
        if (!$connectionId) {
            return Response::error('Connection ID is required', 400);
        }

        $result = CleverReachRequestHelper::request($connectionId, 'GET', '/groups');
        if (!$result['success']) {
            return Response::error($result['message']);
        }

        $groups = [];
        foreach (is_array($result['data']) ? $result['data'] : [] as $group) {
            if (!is_array($group) || !isset($group['id'])) {
                continue;
            }

            $groups[] = [
                'value' => (string) $group['id'],
                'label' => (string) ($group['name'] ?? $group['id']),
            ];
        }

        return Response::success(['groups' => $groups]);
    }

    /**
     * Mappable subscriber fields: email plus global and group-local attributes.
     */
    public function receiverFields(Request $request): Response
    {
        $connectionId = (int) $request->get('connection_id');
        if (!$connectionId) {
            return Response::error('Connection ID is required', 400);
        }

        $columns = [
            [
                'value'    => 'email',
                'label'    => 'Email',
                'required' => true,
            ],
        ];

        $global = $this->fetchAttributes($connectionId, '/attributes');
        if ($global instanceof Response) {
            return $global;
        }
        foreach ($global as $attribute) {
            $columns[] = $attribute;
        }

        // Group-local attributes only exist once a group has been chosen.
        $groupId = trim((string) $request->get('group_id'));
        if ($groupId !== '') {
            $local = $this->fetchAttributes(
                $connectionId,
                '/groups/' . CleverReachRequestHelper::id($groupId) . '/attributes',
                false
            );
            if ($local instanceof Response) {
                return $local;
            }
            foreach ($local as $attribute) {
                $columns[] = $attribute;
            }
        }

        return Response::success(['columns' => $columns]);
    }

    /**
     * Mailings available on the account.
     */
    public function mailings(Request $request): Response
    {
        $connectionId = (int) $request->get('connection_id');
        if (!$connectionId) {
            return Response::error('Connection ID is required', 400);
        }

        $result = CleverReachRequestHelper::request($connectionId, 'GET', '/mailings', [], ['limit' => 100]);
        if (!$result['success']) {
            return Response::error($result['message']);
        }

        $mailings = [];
        foreach (is_array($result['data']) ? $result['data'] : [] as $mailing) {
            if (!is_array($mailing) || !isset($mailing['id'])) {
                continue;
            }

            $label = (string) ($mailing['name'] ?? $mailing['subject'] ?? $mailing['id']);
            $mailings[] = [
                'value' => (string) $mailing['id'],
                'label' => $label,
            ];
        }

        return Response::success(['mailings' => $mailings]);
    }

    /**
     * Reports (sent mailings) available on the account.
     */
    public function reports(Request $request): Response
    {
        $connectionId = (int) $request->get('connection_id');
        if (!$connectionId) {
            return Response::error('Connection ID is required', 400);
        }

        $result = CleverReachRequestHelper::request($connectionId, 'GET', '/reports', [], ['pagesize' => 100]);
        if (!$result['success']) {
            return Response::error($result['message']);
        }

        $reports = [];
        foreach (is_array($result['data']) ? $result['data'] : [] as $report) {
            if (!is_array($report) || !isset($report['id'])) {
                continue;
            }

            $reports[] = [
                'value' => (string) $report['id'],
                'label' => (string) ($report['name'] ?? $report['subject'] ?? $report['id']),
            ];
        }

        return Response::success(['reports' => $reports]);
    }

    /**
     * Fetch an attribute collection and format it as mapping columns.
     *
     * @return array<int, array{value: string, label: string}>|Response
     */
    private function fetchAttributes(int $connectionId, string $path, bool $isGlobal = true): array|Response
    {
        $result = CleverReachRequestHelper::request($connectionId, 'GET', $path);
        if (!$result['success']) {
            return Response::error($result['message']);
        }

        $prefix = $isGlobal
            ? CleverReachReceiverHelper::GLOBAL_PREFIX
            : CleverReachReceiverHelper::LOCAL_PREFIX;
        $suffix = $isGlobal ? ' (global)' : ' (group)';

        $columns = [];
        foreach (is_array($result['data']) ? $result['data'] : [] as $attribute) {
            if (!is_array($attribute)) {
                continue;
            }

            $name = trim((string) ($attribute['name'] ?? ''));
            if ($name === '') {
                continue;
            }

            $columns[] = [
                'value' => $prefix . $name,
                'label' => $name . $suffix,
            ];
        }

        return $columns;
    }
}
