<?php
namespace EasyChat\Library\Messenger\Marketplace;

use EasyChat\Model\Marketplace as MarketplaceModel;








final class MarketplaceAdminPresenter {
    private $model;

    public function __construct($registry, MarketplaceModel $model = null) {
        $this->model = $model ?: new MarketplaceModel($registry);
    }

    public function build(): array {
        $providers = self::providerDefinitions();
        $empty_groups = array_fill_keys(array_keys($providers), []);

        try {
            $accounts = $this->model->listAccounts();
            $streams = $this->model->listAccountStreams();
        } catch (\Throwable $error) {
             
             
            return [
                'providers' => $providers,
                'accounts_by_provider' => $empty_groups,
                'storage_ready' => false,
            ];
        }

        return [
            'providers' => $providers,
            'accounts_by_provider' => self::presentAccounts($accounts, $streams),
            'storage_ready' => true,
        ];
    }

    public static function presentAccounts(array $accounts, array $streams): array {
        $groups = array_fill_keys(array_keys(self::providerDefinitions()), []);
        $streams_by_channel = [];

        foreach ($streams as $stream) {
            $channel_id = (int)($stream['channel_id'] ?? 0);
            if ($channel_id > 0) {
                $streams_by_channel[$channel_id][] = $stream;
            }
        }

        foreach ($accounts as $account) {
            $provider = self::normalizeProvider((string)($account['provider'] ?? ''));
            if ($provider === '') {
                continue;
            }

            $channel_id = (int)($account['channel_id'] ?? 0);
            $capabilities = self::decode((string)($account['capabilities_json'] ?? ''));
            $settings = self::decode((string)($account['settings_json'] ?? ''));
            $presented_streams = [];

            foreach (($streams_by_channel[$channel_id] ?? []) as $stream) {
                $stream_code = (string)($stream['stream'] ?? '');
                $access = is_array($capabilities['stream_access'][$stream_code] ?? null)
                    ? $capabilities['stream_access'][$stream_code]
                    : [];
                $stream['available'] = array_key_exists('available', $access)
                    ? (bool)$access['available']
                    : null;
                $stream['missing_methods'] = is_array($access['missing_read_methods'] ?? null)
                    ? $access['missing_read_methods']
                    : [];
                $presented_streams[] = $stream;
            }

            $account['capabilities'] = $capabilities;
            $account['token_health'] = [
                'type' => (string)($capabilities['token_type'] ?? 'unknown'),
                'label' => (string)($capabilities['token_type_label'] ?? ''),
                'expires_at' => (string)($capabilities['token_expires_at'] ?? ''),
                'read_only' => !empty($capabilities['token_read_only']),
                'permissions' => is_array($capabilities['token_permissions'] ?? null)
                    ? $capabilities['token_permissions']
                    : [],
            ];
            $account['streams'] = $presented_streams;
            $account['has_credentials'] = trim((string)($account['credentials_json'] ?? '')) !== '';
            $account['options'] = [
                'ai_auto_reply' => !empty($settings['ai_auto_reply']),
            ];
            $account['webhook_url'] = $provider === 'yandex_market'
                ? rtrim((string)HTTP_SERVER, '/') . '/index.php?route=messenger/webhook&provider=yandex_market&id='
                    . rawurlencode((string)($account['public_id'] ?? ''))
                : '';
            $account['last_error_message'] = trim((string)($account['last_error'] ?? '')) !== ''
                ? self::errorMessage((string)$account['last_error'])
                : '';
            unset($account['credentials_json'], $account['settings_json'], $account['capabilities_json']);
            $groups[$provider][] = $account;
        }

        return $groups;
    }

    public static function normalizeProvider(string $provider): string {
        $provider = strtolower(trim($provider));
        return isset(self::providerDefinitions()[$provider]) ? $provider : '';
    }

    public static function providerDefinitions(): array {
        return MarketplaceProviderCatalog::all();
    }

    public static function errorMessage(string $code): string {
        $messages = [
            'api_token_required' => 'Введите API-токен Wildberries.',
            'wb_token_format_invalid' => 'Это не похоже на полный токен WB. Скопируйте его целиком из раздела «Интеграции по API».',
            'client_id_required' => 'Введите Client ID кабинета Ozon.',
            'api_key_required' => 'Введите API key кабинета маркетплейса.',
            'auth_failed' => 'Ключ не принят площадкой. Проверьте реквизиты и срок действия.',
            'permission_denied' => 'Ключ работает, но ему не хватает прав на коммуникации.',
            'subscription_required' => 'Для чатов этого кабинета нужна подходящая подписка Ozon.',
            'rate_limited' => 'Площадка временно ограничила частоту запросов. Повторите позже.',
            'marketplace_unavailable' => 'API площадки временно недоступен. Уже подключенные потоки продолжат повторять синхронизацию.',
            'transport_failed' => 'Не удалось установить защищенное соединение с площадкой.',
            'notification_check_failed' => 'Ozon не смог проверить адрес уведомлений. Резервная синхронизация по расписанию продолжит работать.',
            'notification_list_failed' => 'Ключ не даёт управлять уведомлениями Ozon. Резервная синхронизация по расписанию продолжит работать.',
            'notification_setup_failed' => 'Быстрые уведомления Ozon пока не включились. Резервная сверка уже работает.',
            'notification_update_failed' => 'Ozon не обновил адрес быстрых уведомлений. Резервная сверка продолжит работать.',
            'notification_set_failed' => 'Ozon не сохранил адрес быстрых уведомлений. Резервная сверка продолжит работать.',
            'notification_enable_failed' => 'Ozon не включил быстрые уведомления. Резервная сверка продолжит работать.',
            'notification_url_inactive' => 'Ozon не смог обратиться к callback EasyChat. Проверьте HTTPS и доступность сайта извне.',
            'webhook_url_invalid' => 'Адрес EasyChat для уведомлений должен быть публичным HTTPS-адресом без нестандартного порта.',
            'marketplace_account_identity_mismatch' => 'Этот ключ относится к другому кабинету. Подключите его как новый кабинет.',
            'marketplace_account_identity_missing' => 'Wildberries не вернул стабильный ID кабинета. Проверьте тип токена и доступ к сведениям продавца.',
            'marketplace_account_provider_mismatch' => 'Выбранный кабинет относится к другой площадке. Добавьте его отдельным подключением.',
            'marketplace_account_conflict' => 'Этот кабинет уже подключен в EasyChat.',
            'marketplace_account_not_found' => 'Подключенный кабинет не найден. Обновите страницу и повторите действие.',
            'marketplace_account_inactive' => 'Кабинет отключен. Сначала подключите его снова.',
            'marketplace_stream_unknown' => 'EasyChat не распознал этот раздел обращений. Обновите страницу.',
            'marketplace_stream_permission_missing' => 'У ключа нет прав на этот тип обращений.',
            'install_secret_missing' => 'Установка EasyChat не завершила настройку защищенного хранилища. Запустите обновление модуля и повторите подключение.',
            'marketplace_host_not_allowed' => 'EasyChat заблокировал небезопасный адрес внешнего API.',
            'marketplace_response_too_large' => 'Площадка вернула слишком большой ответ. Синхронизация остановлена безопасно и будет повторена позже.',
            'marketplace_cursor_stalled' => 'Площадка не продвинула страницу выдачи. EasyChat ничего не пропустил и повторит сверку позже.',
            'endpoint_or_resource_not_found' => 'Площадка не нашла запрошенный раздел. Проверьте права ключа и доступность функции в кабинете.',
            'marketplace_conflict' => 'Состояние обращения уже изменилось на площадке. EasyChat выполнит сверку.',
            'marketplace_action_outcome_unknown' => 'Площадка не подтвердила результат. EasyChat сначала сверит состояние и не повторит действие вслепую.',
            'marketplace_action_in_progress' => 'Это действие уже отправляется. Дождитесь сверки с площадкой.',
            'marketplace_action_not_allowed' => 'Площадка больше не разрешает это действие. Обновите диалог.',
            'marketplace_action_audit_failed' => 'EasyChat не смог безопасно зарегистрировать действие. Ничего не отправлено, повторите позже.',
            'marketplace_action_failed' => 'Действие не отправлено из-за внутренней ошибки. Обновите обращение и повторите позже.',
            'marketplace_thread_not_found' => 'Обращение не найдено или уже было обновлено. Откройте диалог заново.',
            'marketplace_channel_inactive' => 'Кабинет отключен. Подключите его снова в разделе интеграций.',
            'marketplace_provider_unavailable' => 'Модуль интеграции временно недоступен. Обновите EasyChat и повторите проверку.',
            'review_comment_not_allowed' => 'Ozon не разрешает отвечать на отзыв без текста, фото или видео.',
            'answer_text_required' => 'Введите текст ответа перед публикацией.',
            'answer_text_too_short' => 'Ответ слишком короткий. Добавьте пояснение для покупателя.',
            'message_text_too_long' => 'Текст длиннее лимита площадки. Сократите сообщение и отправьте снова.',
            'attachment_limit_exceeded' => 'Выбрано больше файлов, чем разрешает площадка.',
            'attachment_size_exceeded' => 'Один из файлов или вся группа превышает лимит площадки.',
            'attachment_format_not_supported' => 'Площадка не принимает один из выбранных форматов.',
            'marketplace_attachment_permission_missing' => 'Ключ разрешает читать чат, но не разрешает отправлять файлы.',
            'marketplace_account_required' => 'Выберите подключенный кабинет Ozon.',
            'marketplace_start_permission_missing' => 'У API key нет права создавать чат по отправлению.',
            'marketplace_start_not_supported' => 'Эта площадка не разрешает продавцу начинать диалог.',
            'marketplace_start_failed' => 'Ozon не создал диалог. Проверьте номер отправления и доступность чатов в тарифе.',
            'marketplace_start_message_failed' => 'Чат создан, но первое сообщение не было подтверждено. EasyChat сверит его перед повтором.',
            'marketplace_start_response_invalid' => 'Ozon создал запрос, но не вернул идентификатор чата. EasyChat выполнит сверку.',
            'marketplace_request_id_invalid' => 'Не удалось защитить повторную отправку. Закройте окно и откройте его снова.',
            'ozon_posting_number_invalid' => 'Введите номер отправления Ozon без пробелов.',
            'yandex_market_context_invalid' => 'Выберите заказ или возврат и укажите его числовой ID в Яндекс Маркете.',
            'return_comment_required' => 'Для этого решения площадка требует комментарий.',
            'return_rejection_reason_not_allowed' => 'Эта причина больше недоступна для заявки. Обновите диалог.',
            'return_amount_invalid' => 'Проверьте сумму компенсации или обратной доставки.',
            'csrf_validation_failed' => 'Сессия устарела. Обновите страницу и повторите действие.',
        ];

        return $messages[$code] ?? 'Не удалось выполнить действие. Проверьте состояние подключения и повторите попытку.';
    }

    private static function decode(string $json): array {
        $value = json_decode($json, true);
        return is_array($value) ? $value : [];
    }
}
