<?php
namespace EasyChat\Library\Delivery;

use EasyChat\Library\Messenger\SecretBox;
use EasyChat\Library\Commerce\OpenCartShippingResolver;
use EasyChat\Model\Setting;

 
final class DeliveryConnection
{
    private $registry;
    private $settings;

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

    public function publicState(): array
    {
        $all = $this->settings->getAll();
        $resolver = new OpenCartShippingResolver();
        $post_login = $this->decrypt((string)($all['chat_tracking_russian_post_login'] ?? ''), $all);
        $post_password = $this->decrypt((string)($all['chat_tracking_russian_post_password'] ?? ''), $all);
        $cdek_id = $this->decrypt((string)($all['chat_tracking_cdek_client_id'] ?? ''), $all);
        $cdek_secret = $this->decrypt((string)($all['chat_tracking_cdek_client_secret'] ?? ''), $all);
        $yandex_token = $this->decrypt((string)($all['chat_tracking_yandex_delivery_token'] ?? ''), $all);
        $apiship_token = $this->decrypt((string)($all['chat_tracking_apiship_token'] ?? ''), $all);
        return array(
            'russian_post' => array(
                'enabled' => (string)($all['chat_tracking_russian_post_enabled'] ?? '0') === '1',
                'credentials_saved' => $post_login !== '' && $post_password !== '',
                'login_mask' => SecretBox::mask($post_login),
            ),
            'cdek' => array(
                'enabled' => (string)($all['chat_tracking_cdek_enabled'] ?? '0') === '1',
                'credentials_saved' => $cdek_id !== '' && $cdek_secret !== '',
                'client_id_mask' => SecretBox::mask($cdek_id),
            ),
            'yandex_delivery' => array(
                'enabled' => (string)($all['chat_tracking_yandex_delivery_enabled'] ?? '0') === '1',
                'credentials_saved' => $yandex_token !== '',
                'token_mask' => SecretBox::mask($yandex_token),
            ),
            'apiship' => array(
                'enabled' => (string)($all['chat_tracking_apiship_enabled'] ?? '0') === '1',
                'credentials_saved' => $apiship_token !== '',
                'token_mask' => SecretBox::mask($apiship_token),
            ),
            'opencart_shipping_mapping' => $resolver->mappingFromSettings((string)($all['opencart_shipping_mapping'] ?? '')),
        );
    }

    public function credentials(string $provider): array
    {
        $all = $this->settings->getAll();
        if ($provider === 'russian_post') {
            return array(
                'enabled' => (string)($all['chat_tracking_russian_post_enabled'] ?? '0') === '1',
                'login' => $this->decrypt((string)($all['chat_tracking_russian_post_login'] ?? ''), $all),
                'password' => $this->decrypt((string)($all['chat_tracking_russian_post_password'] ?? ''), $all),
            );
        }
        if ($provider === 'cdek') {
            return array(
                'enabled' => (string)($all['chat_tracking_cdek_enabled'] ?? '0') === '1',
                'client_id' => $this->decrypt((string)($all['chat_tracking_cdek_client_id'] ?? ''), $all),
                'client_secret' => $this->decrypt((string)($all['chat_tracking_cdek_client_secret'] ?? ''), $all),
            );
        }
        if ($provider === 'yandex_delivery' || $provider === 'apiship') {
            $key = 'chat_tracking_' . $provider . '_token';
            return array(
                'enabled' => (string)($all['chat_tracking_' . $provider . '_enabled'] ?? '0') === '1',
                'token' => $this->decrypt((string)($all[$key] ?? ''), $all),
            );
        }
        return array('enabled' => false);
    }

    public function save(array $input): array
    {
        $all = $this->settings->getAll();
        $updates = array();
        foreach (array(
            'russian_post' => array('login', 'password'),
            'cdek' => array('client_id', 'client_secret'),
            'yandex_delivery' => array('token'),
            'apiship' => array('token'),
        ) as $provider => $fields) {
            $enabled = !empty($input[$provider]['enabled']);
            $updates['chat_tracking_' . $provider . '_enabled'] = $enabled ? '1' : '0';
            foreach ($fields as $field) {
                $key = 'chat_tracking_' . $provider . '_' . $field;
                $plain = trim((string)($input[$provider][$field] ?? ''));
                $updates[$key] = $plain === ''
                    ? (string)($all[$key] ?? '')
                    : SecretBox::encrypt($plain, $this->secret($all));
            }
            if ($enabled) {
                foreach ($fields as $field) {
                    $key = 'chat_tracking_' . $provider . '_' . $field;
                    if ($this->decrypt((string)$updates[$key], $all) === '') {
                        throw new \InvalidArgumentException($provider . '_credentials_required');
                    }
                }
            }
        }
        $raw_mapping = trim((string)($input['opencart_shipping_mapping'] ?? ''));
        if ($raw_mapping !== '') {
            $decoded_mapping = json_decode($raw_mapping, true);
            if (!is_array($decoded_mapping) || json_last_error() !== JSON_ERROR_NONE) {
                 
                 
                 
                throw new \InvalidArgumentException('opencart_shipping_mapping_invalid');
            }
        }
        $mapping = (new OpenCartShippingResolver())->mappingFromSettings($raw_mapping);
        $updates['opencart_shipping_mapping'] = json_encode($mapping, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        $this->settings->setManyAtomic($updates);
        return $this->publicState();
    }

    private function decrypt(string $value, array $all): string
    {
        if ($value === '') return '';
        return SecretBox::decrypt($value, $this->secret($all));
    }

    private function secret(array $all): string
    {
        $secret = trim((string)($all['chat_install_secret'] ?? ''));
        if ($secret === '') throw new \RuntimeException('install_secret_required');
        return $secret;
    }
}
