<?php

namespace App\Services\Courier;

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

class CourierSettingsService
{
    public function getIntegrationSettings(): array
    {
        $settings = array_replace_recursive(
            $this->defaultIntegrationSettings(),
            Helpers::get_business_settings('courier_integration') ?? []
        );
        $settings['allowed_booking_statuses'] = $this->normalizeAllowedBookingStatuses(
            Arr::wrap(Arr::get($settings, 'allowed_booking_statuses', []))
        );

        return $settings;
    }

    public function getSenderProfile(): array
    {
        return array_replace_recursive($this->defaultSenderProfile(), Helpers::get_business_settings('courier_sender_profile') ?? []);
    }

    public function getProviderConfig(string $provider = 'steadfast', bool $decryptSecrets = true): array
    {
        $settings = Helpers::get_business_settings('courier_provider_' . $provider) ?? [];
        $config = array_replace_recursive($this->defaultProviderConfig($provider), $settings);

        if ($decryptSecrets) {
            foreach (['api_key', 'secret_key', 'webhook_bearer_token'] as $secretField) {
                $config[$secretField] = $this->decryptValue(Arr::get($config, $secretField));
            }
        }

        return $config;
    }

    public function getActiveProvider(): string
    {
        return Arr::get($this->getIntegrationSettings(), 'default_provider', 'steadfast');
    }

    public function getActiveProviderConfig(bool $decryptSecrets = true): array
    {
        return $this->getProviderConfig($this->getActiveProvider(), $decryptSecrets);
    }

    public function isIntegrationEnabled(): bool
    {
        $integration = $this->getIntegrationSettings();
        $provider = $this->getActiveProviderConfig();

        return (bool) Arr::get($integration, 'enabled') && (bool) Arr::get($provider, 'enabled');
    }

    public function saveSettings(array $validatedData): void
    {
        $existingProvider = $this->getProviderConfig('steadfast', false);

        $providerConfig = [
            'enabled' => (bool) Arr::get($validatedData, 'provider_enabled', false),
            'base_url' => trim((string) Arr::get($validatedData, 'base_url', '')),
            'booking_path' => trim((string) Arr::get($validatedData, 'booking_path', '')),
            'status_by_consignment_path' => trim((string) Arr::get($validatedData, 'status_by_consignment_path', '')),
            'status_by_invoice_path' => trim((string) Arr::get($validatedData, 'status_by_invoice_path', '')),
            'status_by_tracking_path' => trim((string) Arr::get($validatedData, 'status_by_tracking_path', '')),
            'api_key' => $this->prepareEncryptedValue(
                Arr::get($validatedData, 'api_key'),
                Arr::get($existingProvider, 'api_key')
            ),
            'secret_key' => $this->prepareEncryptedValue(
                Arr::get($validatedData, 'secret_key'),
                Arr::get($existingProvider, 'secret_key')
            ),
            'webhook_bearer_token' => $this->prepareEncryptedValue(
                Arr::get($validatedData, 'webhook_bearer_token'),
                Arr::get($existingProvider, 'webhook_bearer_token')
            ),
        ];

        $integration = [
            'enabled' => (bool) Arr::get($validatedData, 'enabled', false),
            'default_provider' => 'steadfast',
            'mode' => Arr::get($validatedData, 'mode', 'sandbox'),
            'manual_sync_enabled' => (bool) Arr::get($validatedData, 'manual_sync_enabled', false),
            'auto_sync_enabled' => (bool) Arr::get($validatedData, 'auto_sync_enabled', false),
            'allowed_booking_statuses' => Arr::wrap(Arr::get($validatedData, 'allowed_booking_statuses', ['confirmed', 'accepted', 'processing'])),
        ];

        $senderProfile = [
            'sender_name' => trim((string) Arr::get($validatedData, 'sender_name', '')),
            'sender_phone' => trim((string) Arr::get($validatedData, 'sender_phone', '')),
            'sender_address' => trim((string) Arr::get($validatedData, 'sender_address', '')),
            'sender_district' => trim((string) Arr::get($validatedData, 'sender_district', '')),
            'default_parcel_note' => trim((string) Arr::get($validatedData, 'default_parcel_note', '')),
        ];

        Helpers::businessUpdateOrInsert(['key' => 'courier_integration'], ['value' => json_encode($integration)]);
        Helpers::businessUpdateOrInsert(['key' => 'courier_sender_profile'], ['value' => json_encode($senderProfile)]);
        Helpers::businessUpdateOrInsert(['key' => 'courier_provider_steadfast'], ['value' => json_encode($providerConfig)]);

        $this->flushBusinessSettingCache();
    }

    public function defaultIntegrationSettings(): array
    {
        return [
            'enabled' => false,
            'default_provider' => 'steadfast',
            'mode' => 'sandbox',
            'manual_sync_enabled' => true,
            'auto_sync_enabled' => false,
            'allowed_booking_statuses' => ['confirmed', 'accepted', 'processing'],
        ];
    }

    public function defaultSenderProfile(): array
    {
        return [
            'sender_name' => '',
            'sender_phone' => '',
            'sender_address' => '',
            'sender_district' => '',
            'default_parcel_note' => 'Handle with care',
        ];
    }

    public function defaultProviderConfig(string $provider = 'steadfast'): array
    {
        if ($provider !== 'steadfast') {
            return [];
        }

        return [
            'enabled' => false,
            'base_url' => 'https://portal.packzy.com/api/v1',
            'booking_path' => '/create_order',
            'status_by_consignment_path' => '/status_by_cid/{consignment_id}',
            'status_by_invoice_path' => '/status_by_invoice/{invoice}',
            'status_by_tracking_path' => '/status_by_trackingcode/{tracking_code}',
            'api_key' => null,
            'secret_key' => null,
            'webhook_bearer_token' => 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 normalizeAllowedBookingStatuses(array $statuses): array
    {
        $statuses = array_values(array_unique(array_filter(
            array_map(static fn ($status) => trim((string) $status), $statuses),
            static fn ($status) => in_array($status, ['confirmed', 'accepted', 'processing'], true)
        )));

        if (in_array('confirmed', $statuses, true) && ! in_array('accepted', $statuses, true)) {
            $statuses[] = 'accepted';
        }

        return $statuses;
    }

    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');

        foreach (['courier_integration_conf', 'courier_sender_profile_conf', 'courier_provider_steadfast_conf'] as $configKey) {
            Config::set($configKey, null);
        }
    }
}
