<?php

namespace App\Providers;

use App\Helpers\ArrayHelper;
use App\Models\Blog;
use App\Models\Domain;
use App\Models\Menu;
use App\Models\Plan;
use App\Models\Username;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\ServiceProvider;
use Inerba\DbConfig\DbConfig;
use Laravel\Cashier\Cashier;

class AppServiceProvider extends ServiceProvider
{
    private array $appConfig;

    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        $this->loadConfiguration();
        $this->loadDomainUsernameData();

        // Only load application data when not in testing environment
        if (! $this->app->environment('testing')) {
            $this->loadApplicationData();
        }

        Cashier::calculateTaxes();
    }

    /**
     * Load application data and cache it.
     */
    private function loadApplicationData(): void
    {
        try {
            $settings = cache()->remember('app_settings', now()->addHours(6), fn (): array => (array) DB::table('settings')->find(1));

            $menus = cache()->remember('app_menus', now()->addHours(6), fn () => Menu::all()->toArray());

            $blogs = cache()->remember('app_blogs', now()->addHours(6), fn () => Blog::query()->where('is_published', 1)->get()->toArray());

            $plans = cache()->remember('app_plans', now()->addHours(6), fn () => Plan::all()->toArray());

            $legacySettings = cache()->remember('legacy_app_settings', now()->addHours(6), fn (): array => $this->loadLegacySettings());
            config(['app.settings' => (array) $legacySettings]);
            config(['app.menus' => $menus]);
            config(['app.blogs' => $blogs]);
            config(['app.plans' => $plans]);
        } catch (Exception) {
            // Fail silently if database is not available
            // This allows the application to boot during migrations and testing
        }
    }

    private function loadConfiguration(): void
    {
        try {
            $websiteGroup = DbConfig::getGroup('website') ?? [];
            $imapGroup = DbConfig::getGroup('imap') ?? [];
            $configurationGroup = DbConfig::getGroup('configuration') ?? [];
            $this->appConfig['website_settings'] = (in_array($websiteGroup, [null, []], true)) ? [] : $websiteGroup;
            $this->appConfig['imap_settings'] = (in_array($imapGroup, [null, []], true)) ? [] : $imapGroup;
            $this->appConfig['configuration_settings'] = (in_array($configurationGroup, [null, []], true)) ? [] : $configurationGroup;
        } catch (\Exception $e) {
            $this->appConfig = [
                'website_settings' => [],
                'imap_settings' => [],
                'configuration_settings' => []
            ];
            Log::error($e->getMessage());
        }
    }

    private function loadDomainUsernameData(): void
    {
        try {
            // Use new array scopes to get data in the desired format
            $domains = Domain::getActiveDomains();
            $usernames = Username::getActiveUsernames();

            // Merge into domain config for legacy compatibility
            $domainUsernameConfig = array_merge($domains, $usernames);
            $this->appConfig['configuration_settings'] = array_merge($this->appConfig['configuration_settings'], $domainUsernameConfig);
        } catch (\Exception $e) {
            $domainUsernameConfig = [
                'domains' => [],
                'premium_domains' => [],
                'gmailUsernames' => [],
                'premium_gmailUsernames' => [],
                'outlookUsernames' => [],
                'premium_outlookUsernames' => [],
            ];
            $this->appConfig['configuration_settings'] = array_merge($this->appConfig['configuration_settings'], $domainUsernameConfig);
            Log::error($e->getMessage());
        }
    }

    private function loadLegacySettings(): array
    {
        return [
            "app_name" => $this->getConfig('website_settings.app_name'),
            "app_version" => $this->getConfig('website_settings.app_version'),
            "app_base_url" => $this->getConfig('website_settings.app_base_url'),
            "app_admin" => $this->getConfig('website_settings.app_admin'),
            "app_title" => $this->getConfig('website_settings.app_title'),
            "app_description" => $this->getConfig('website_settings.app_description'),
            "app_keywords" => $this->getConfig('website_settings.app_keywords'),
            "app_contact" => $this->getConfig('website_settings.app_contact'),
            "app_meta" => ArrayHelper::jsonEncodeSafe($this->getConfig('website_settings.app_meta')),
            "app_social" => ArrayHelper::jsonEncodeSafe($this->getConfig('website_settings.app_social')),
            "app_header" => $this->getConfig('website_settings.app_header'),
            "app_footer" => $this->getConfig('website_settings.app_footer'),
            "imap_settings" => ArrayHelper::jsonEncodeSafe([
                "host" => $this->getConfig('imap_settings.public.host'),
                "port" => $this->getConfig('imap_settings.public.port'),
                "username" => $this->getConfig('imap_settings.public.username'),
                "password" => $this->getConfig('imap_settings.public.password'),
                "encryption" => $this->getConfig('imap_settings.public.encryption'),
                "validate_cert" => $this->getConfig('imap_settings.public.validate_cert'),
                "default_account" => $this->getConfig('imap_settings.public.default_account'),
                "protocol" => $this->getConfig('imap_settings.public.protocol'),
                "cc_check" => $this->getConfig('imap_settings.public.cc_check'),
                "premium_host" => $this->getConfig('imap_settings.premium.host'),
                "premium_port" => $this->getConfig('imap_settings.premium.port'),
                "premium_username" => $this->getConfig('imap_settings.premium.username'),
                "premium_password" => $this->getConfig('imap_settings.premium.password'),
                "premium_encryption" => $this->getConfig('imap_settings.premium.premium_encryption'),
                "premium_validate_cert" => $this->getConfig('imap_settings.premium.validate_cert'),
                "premium_default_account" => $this->getConfig('imap_settings.premium.default_account'),
                "premium_protocol" => $this->getConfig('imap_settings.premium.protocol'),
                "premium_cc_check" => $this->getConfig('imap_settings.premium.cc_check'),
            ]),
            "configuration_settings" => ArrayHelper::jsonEncodeSafe($this->appConfig['configuration_settings']),
            "ads_settings" => ArrayHelper::jsonEncodeSafe($this->getConfig('website_settings.ads_settings')),
        ];
    }

    private function getConfig(string $key, $default = null)
    {
        return ArrayHelper::getValueFromArray($key, $this->appConfig) ?? $default;
    }
}
