<?php
namespace EasyChat\Library\Messenger;

use EasyChat\Model\Messenger as MessengerModel;
use EasyChat\Model\Marketplace as MarketplaceModel;
use EasyChat\Model\Session as SessionModel;
use EasyChat\Library\Messenger\Marketplace\MarketplaceStream;

class ReplyCapability {

    const WRITABLE = 'writable';
    const READ_ONLY = 'read_only';

    private $registry;

    public function __construct($registry) {
        $this->registry = $registry;
    }

    public static function forMaxChatType(string $chat_type): array {
        return self::payload(
            false,
            strtoupper(trim($chat_type)) ?: 'unknown',
            'personal_max_retired',
            'История MAX доступна только для чтения',
            'Подключение личной учётной записи MAX удалено. Ранее полученные сообщения сохранены.'
        );
    }

    public function forChatRow(array $chat): array {
        $provider = strtolower((string)($chat['source_provider'] ?? 'widget'));
        if (in_array($provider, [WildberriesProvider::PROVIDER, OzonProvider::PROVIDER, YandexMarketProvider::PROVIDER], true)) {
            return $this->forMarketplaceChat($provider, $chat);
        }
        if ($provider !== 'max') {
            return self::payload(true, '', '', '', '');
        }

        $metadata = $this->metadataFromRow($chat);
        return self::forMaxChatType(MaxConversationIdentity::chatTypeFromMetadata($metadata));
    }

    public function forChatId(int $chat_id): array {
        if ($chat_id <= 0) {
            return self::payload(false, '', 'chat_missing', 'Диалог недоступен', 'Откройте другой диалог или обновите список.');
        }

        $session = (new SessionModel($this->registry))->getSessionById($chat_id);
        if (!$session) {
            return self::payload(false, '', 'chat_missing', 'Диалог недоступен', 'Откройте другой диалог или обновите список.');
        }

        $provider = strtolower((string)($session['source_provider'] ?? 'widget'));
        if ($provider === 'max' && empty($session['contact_metadata_json']) && !empty($session['external_contact_id'])) {
            $contact = (new MessengerModel($this->registry))->getContactById((int)$session['external_contact_id']);
            if ($contact) {
                $session['contact_metadata_json'] = (string)($contact['metadata_json'] ?? '');
            }
        }
        if (in_array($provider, [WildberriesProvider::PROVIDER, OzonProvider::PROVIDER, YandexMarketProvider::PROVIDER], true)
            && empty($session['marketplace_capabilities_json'])) {
            $thread = (new MarketplaceModel($this->registry))->getThreadByChat($chat_id);
            if ($thread) {
                $session['marketplace_capabilities_json'] = (string)($thread['capabilities_json'] ?? '');
                $session['marketplace_state'] = (string)($thread['state'] ?? '');
                $session['marketplace_conversation_kind'] = (string)($thread['conversation_kind'] ?? '');
            }
        }

        return $this->forChatRow($session);
    }

    public static function metadataForMaxChatType(string $chat_type): array {
        $payload = self::forMaxChatType($chat_type);
        return [
            'max_chat_type' => $payload['chat_type'],
            'reply_capability' => $payload['can_reply'] ? self::WRITABLE : self::READ_ONLY,
            'reply_reason' => (string)$payload['reason'],
        ];
    }

    private static function payload(bool $can_reply, string $chat_type, string $reason, string $title, string $message): array {
        return [
            'can_reply' => $can_reply,
            'can_suggest_reply' => $can_reply,
            'can_auto_reply' => $can_reply,
            'status' => $can_reply ? self::WRITABLE : self::READ_ONLY,
            'chat_type' => $chat_type,
            'reason' => $reason,
            'auto_reply_reason' => $can_reply ? '' : $reason,
            'title' => $title,
            'message' => $message,
        ];
    }

    private function forMarketplaceChat(string $provider, array $chat): array {
        $kind = MarketplaceStream::normalize((string)(
            $chat['marketplace_conversation_kind']
            ?? $chat['conversation_kind']
            ?? ''
        ));
        $state = strtolower(trim((string)($chat['marketplace_state'] ?? '')));
        $raw = (string)($chat['marketplace_capabilities_json'] ?? '');
        $capabilities = $raw !== '' ? json_decode($raw, true) : [];
        $capabilities = is_array($capabilities) ? $capabilities : [];

         
         
         
         
        $known_writable_state = $state === '' || in_array($state, [
            'open', 'opened', 'active', 'buyer_seller', 'buyer-seller',
        ], true);
        $can_reply = $kind === MarketplaceStream::BUYER_CHAT
            && !empty($capabilities['can_reply'])
            && $known_writable_state;
        if ($can_reply) {
            $payload = self::payload(true, $kind, '', '', '');
            $payload['conversation_kind'] = $kind;
            $payload['actions'] = [];
            $payload['provider'] = $provider;
            $payload['can_send_attachments'] = !array_key_exists('attachments_out', $capabilities)
                || !empty($capabilities['attachments_out']);
            return $payload;
        }

        $labels = [
            MarketplaceStream::QUESTION => [
                'marketplace_question_action_required',
                'Вопрос о товаре',
                'Подготовьте ответ и отправьте его через действие вопроса после проверки.',
            ],
            MarketplaceStream::REVIEW => [
                'marketplace_review_action_required',
                'Отзыв покупателя',
                'Подготовьте ответ и опубликуйте его через действие отзыва после проверки.',
            ],
            MarketplaceStream::RETURN_CLAIM => [
                'marketplace_return_action_required',
                'Заявка на возврат',
                'Выберите только одно из действий, которые разрешил маркетплейс для этой заявки.',
            ],
        ];
        if (isset($labels[$kind])) {
            [$reason, $title, $message] = $labels[$kind];
        } elseif (!$known_writable_state) {
            $reason = 'marketplace_thread_closed';
            $title = 'Диалог закрыт';
            $message = 'Маркетплейс больше не разрешает отвечать в этот диалог.';
        } else {
            $reason = 'marketplace_capability_unknown';
            $title = 'Ответ временно недоступен';
            $message = 'EasyChat уточняет возможности этого обращения у маркетплейса.';
        }

        $payload = self::payload(false, $kind !== '' ? $kind : 'unknown', $reason, $title, $message);
        $payload['conversation_kind'] = $kind !== '' ? $kind : 'unknown';
        $payload['actions'] = is_array($capabilities['actions'] ?? null) ? $capabilities['actions'] : [];
         
         
        $payload['action_targets'] = is_array($capabilities['action_targets'] ?? null)
            ? $capabilities['action_targets']
            : [];
        $payload['draft_only'] = !empty($capabilities['draft_only']);
        $payload['review_commentable'] = !array_key_exists('review_commentable', $capabilities)
            || !empty($capabilities['review_commentable']);
        $payload['workflow_actions'] = is_array($capabilities['workflow_actions'] ?? null)
            ? $capabilities['workflow_actions']
            : [];
        $payload['allowed_claim_actions'] = is_array($capabilities['allowed_claim_actions'] ?? null)
            ? $capabilities['allowed_claim_actions']
            : [];
        $payload['return_rejection_reasons'] = is_array($capabilities['return_rejection_reasons'] ?? null)
            ? $capabilities['return_rejection_reasons']
            : [];
        $payload['provider'] = $provider;
        $payload['can_send_attachments'] = false;
        return $payload;
    }

    private function metadataFromRow(array $row): array {
        $raw = (string)($row['contact_metadata_json'] ?? $row['metadata_json'] ?? '');
        if ($raw === '') {
            return [];
        }
        $metadata = json_decode($raw, true);
        return is_array($metadata) ? $metadata : [];
    }
}
