<?php

use Daylight\Core\DaylightServiceProvider;
use Daylight\Core\Models\Shipping\ShippingClass;
use Daylight\Core\Models\Shipping\ShippingZone;
use Daylight\Core\Models\Shipping\ShippingZoneRule;
use Daylight\Core\Models\Translations\AttributeTranslation;
use Daylight\Core\Models\Translations\AttributeValueTranslation;
use Daylight\Core\Models\Translations\BrandTranslation;
use Daylight\Core\Models\Translations\CategoryTranslation;
use Daylight\Core\Models\Translations\LabelTranslation;
use Daylight\Core\Models\Translations\OptionTranslation;
use Daylight\Core\Models\Translations\OptionValueTranslation;
use Daylight\Core\Models\Translations\PageTranslation;
use Daylight\Core\Models\Translations\ProductTranslation;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

if (! function_exists('currentDaylightVersion')) {
    function currentDaylightVersion(): string
    {
        return DaylightServiceProvider::CURRENT_VERSION ?? 'Unknown';
    }
}

if (! function_exists('translatedRoute')) {
    function translatedRoute($name, $parameters = [], $lang = null, $absolute = true)
    {
        if ($lang && in_array($lang, config('multilingualism.available_locales'))) {
            return app('url')->route($lang . '_' . $name, $parameters, $absolute);
        }

        $locale_prefix = config('multilingualism.locale_prefix');

        if (empty($locale_prefix)) {
            $locale_prefix = app()->getLocale();
        }

        if (empty($locale_prefix)) {
            $locale_prefix = config('app.fallback_locale');
        }

        return app('url')->route($locale_prefix . '_' . $name, $parameters, $absolute);
    }
}

if (! function_exists('daylightAsset')) {
    function daylightAsset(string $path): string
    {
        static $manifests = [];

        $reloadPath = public_path('vendor/daylight/hot');

        if (file_exists($reloadPath)) {
            return file_get_contents($reloadPath) . '/' . $path;
        }

        $manifestPath = public_path('vendor/daylight/build/manifest.json');

        if (! isset($manifests[$manifestPath])) {
            if (! file_exists($manifestPath)) {
                if (app()->runningInConsole()) {
                    return false;
                }

                throw new RuntimeException("Vite manifest not found at [$manifestPath].");
            }

            $manifests[$manifestPath] = json_decode(file_get_contents($manifestPath), true);
        }

        $manifest = $manifests[$manifestPath];

        if (! isset($manifest[$path])) {
            return asset("vendor/daylight/build/{$manifest[$path]['file']}");
        }

        return asset("vendor/daylight/build/{$manifest[$path]['file']}");
    }
}

if (! function_exists('formatPrice')) {
    function formatPrice(mixed $price, int $decimals = 2): string
    {
        if (app()->getLocale() == 'fr') {
            return number_format($price / 100, $decimals, ',', ' ') . ' €';
        }

        if (in_array(app()->getLocale(), ['de', 'es'])) {
            return number_format($price / 100, $decimals, ',', '.') . ' €';
        }

        return '€ ' . number_format($price / 100, $decimals, ',', '.');
    }
}

if (! function_exists('formatBytes')) {
    function formatBytes($size, $precision = 2): string
    {
        if ($size > 0) {
            $size = (int) $size;
            $base = log($size) / log(1024);
            $suffixes = [' bytes', ' KB', ' MB', ' GB', ' TB'];

            return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
        } else {
            return $size;
        }
    }
}

if (! function_exists('formatNumber')) {
    function formatNumber(mixed $amount, int $decimals = 0)
    {
        if (app()->getLocale() == 'fr') {
            return number_format($amount, $decimals, ',', ' ');
        }

        return number_format($amount, $decimals, ',', '.');
    }
}

if (! function_exists('getFileExtension')) {
    function getFileExtension(string $filename): string
    {
        return pathinfo($filename, PATHINFO_EXTENSION);
    }
}

if (! function_exists('daylightModel')) {
    /**
     * Resolve the fully qualified model class name from the daylight config.
     * Falls back to Daylight\Core defaults when no override is provided.
     *
     * @return class-string<Model>
     */
    function daylightModel(string $key): string
    {
        $class = config('daylight.models.' . $key);

        if (is_string($class) && class_exists($class)) {
            return $class;
        }

        // Provide a safe fallback to the package default namespace
        $fallbackNamespace = 'Daylight\\Core\\Models\\';

        $fallbackMap = [
            'shipping_class' => ShippingClass::class,
            'shipping_zone' => ShippingZone::class,
            'shipping_zone_rule' => ShippingZoneRule::class,
            'attribute_translation' => AttributeTranslation::class,
            'attribute_value_translation' => AttributeValueTranslation::class,
            'brand_translation' => BrandTranslation::class,
            'category_translation' => CategoryTranslation::class,
            'label_translation' => LabelTranslation::class,
            'option_translation' => OptionTranslation::class,
            'option_value_translation' => OptionValueTranslation::class,
            'page_translation' => PageTranslation::class,
            'product_translation' => ProductTranslation::class,
        ];

        $className = $fallbackMap[$key] ?? '\Daylight\Core\Models\\' . Str::pascal($key);

        if (! $className) {
            throw new RuntimeException("Unable to resolve model key [$key] to a class.");
        }

        return $className;
    }
}
