<?php

namespace App\Services\AiChat;

use App\CentralLogics\Helpers;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Crypt;

class MetaChatSettingsService
{
    public function getSettings(bool $decryptSecrets = true): array
    {
        $settings = array_replace_recursive(
            $this->defaultSettings(),
            Helpers::get_business_settings('ai_chat_meta_channels') ?? []
        );

        if ($decryptSecrets) {
            $settings['whatsapp']['access_token'] = $this->decryptValue(Arr::get($settings, 'whatsapp.access_token'));
            $settings['messenger']['page_access_token'] = $this->decryptValue(Arr::get($settings, 'messenger.page_access_token'));
        }

        return $settings;
    }

    public function getChannelConfig(string $channel, bool $decryptSecrets = true): array
    {
        return Arr::get($this->getSettings($decryptSecrets), $channel, []);
    }

    public function getVerifyToken(string $channel): ?string
    {
        return Arr::get($this->getChannelConfig($channel, true), 'verify_token');
    }

    public function isMasterEnabled(): bool
    {
        return (bool) Arr::get($this->getSettings(), 'enabled', false);
    }

    public function isChannelEnabled(string $channel): bool
    {
        return $this->isMasterEnabled()
            && (bool) Arr::get($this->getChannelConfig($channel), 'enabled', false);
    }

    public function saveSettings(array $validatedData): void
    {
        $existing = $this->getSettings(false);

        $settings = [
            'enabled' => (bool) Arr::get($validatedData, 'meta_channels_enabled', false),
            'graph_version' => trim((string) Arr::get($validatedData, 'meta_graph_version', 'v23.0')),
            'whatsapp' => [
                'enabled' => (bool) Arr::get($validatedData, 'whatsapp_enabled', false),
                'verify_token' => trim((string) Arr::get($validatedData, 'whatsapp_verify_token', '')),
                'access_token' => $this->prepareEncryptedValue(
                    Arr::get($validatedData, 'whatsapp_access_token'),
                    Arr::get($existing, 'whatsapp.access_token')
                ),
                'phone_number_id' => trim((string) Arr::get($validatedData, 'whatsapp_phone_number_id', '')),
                'business_account_id' => trim((string) Arr::get($validatedData, 'whatsapp_business_account_id', '')),
            ],
            'messenger' => [
                'enabled' => (bool) Arr::get($validatedData, 'messenger_enabled', false),
                'verify_token' => trim((string) Arr::get($validatedData, 'messenger_verify_token', '')),
                'page_access_token' => $this->prepareEncryptedValue(
                    Arr::get($validatedData, 'messenger_page_access_token'),
                    Arr::get($existing, 'messenger.page_access_token')
                ),
                'page_id' => trim((string) Arr::get($validatedData, 'messenger_page_id', '')),
            ],
        ];

        Helpers::businessUpdateOrInsert(['key' => 'ai_chat_meta_channels'], [
            'value' => json_encode($settings),
        ]);

        $this->flushBusinessSettingCache();
    }

    public function defaultSettings(): array
    {
        return [
            'enabled' => false,
            'graph_version' => 'v23.0',
            'whatsapp' => [
                'enabled' => false,
                'verify_token' => null,
                'access_token' => null,
                'phone_number_id' => null,
                'business_account_id' => null,
            ],
            'messenger' => [
                'enabled' => false,
                'verify_token' => null,
                'page_access_token' => null,
                'page_id' => null,
            ],
        ];
    }

    private function prepareEncryptedValue(?string $incomingValue, ?string $existingEncryptedValue = null): ?string
    {
        $incomingValue = is_string($incomingValue) ? trim($incomingValue) : null;

        if (blank($incomingValue)) {
            return $existingEncryptedValue;
        }

        return Crypt::encryptString($incomingValue);
    }

    private function decryptValue(?string $value): ?string
    {
        if (blank($value)) {
            return null;
        }

        try {
            return Crypt::decryptString($value);
        } catch (DecryptException) {
            return $value;
        }
    }

    private function flushBusinessSettingCache(): void
    {
        Cache::forget('business_settings_all_data');
        Config::set('ai_chat_meta_channels_conf', null);
    }
}
