<?php

namespace App\Support\Concerns;

use App\Models\Package;

trait PresentsPackages
{
    protected function presentPackage(Package $package): array
    {
        $package->append('limits');

        $packageArray = $package->toArray();
        $features = $packageArray['features'] ?? [];
        $features = $this->normaliseFeatures($features);
        $watermarkRemovalAllowed = in_array('no_watermark', $features, true) || in_array('watermark_removal', $features, true);
        $watermarkPolicy = $watermarkRemovalAllowed ? 'none' : 'basic';

        $locale = app()->getLocale();
        $name = $this->resolveTranslation($package->name_translations ?? null, $package->name ?? '', $locale);
        $descriptionTemplate = $this->resolveTranslation($package->description_translations ?? null, $package->description ?? '', $locale);

        $replacements = $this->buildPlaceholderReplacements($package);
        $description = trim($this->applyPlaceholders($descriptionTemplate, $replacements));

        $table = $package->description_table ?? [];
        if (is_string($table)) {
            $decoded = json_decode($table, true);
            $table = is_array($decoded) ? $decoded : [];
        }

        $table = array_map(function (array $row) use ($replacements) {
            return [
                'title' => trim($this->applyPlaceholders($row['title'] ?? '', $replacements)),
                'value' => trim($this->applyPlaceholders($row['value'] ?? '', $replacements)),
            ];
        }, $table);
        $table = array_values($table);

        $galleryDuration = $replacements['{{gallery_duration}}'] ?? null;

        return [
            'id' => $package->id,
            'name' => $name,
            'slug' => $package->slug,
            'type' => $package->type,
            'included_package_slug' => $package->included_package_slug,
            'price' => $package->price,
            'paddle_product_id' => $package->paddle_product_id,
            'paddle_price_id' => $package->paddle_price_id,
            'description' => $description,
            'description_breakdown' => $table,
            'gallery_duration_label' => $galleryDuration,
            'events' => $package->type === 'endcustomer' ? 1 : ($package->max_events_per_year ?? null),
            'features' => $features,
            'watermark_policy' => $watermarkPolicy,
            'limits' => $package->limits,
            'max_photos' => $package->max_photos,
            'max_guests' => $package->max_guests,
            'max_tasks' => $package->max_tasks,
            'gallery_days' => $package->gallery_days,
            'max_events_per_year' => $package->max_events_per_year,
            'watermark_allowed' => (bool) $package->watermark_allowed,
            'branding_allowed' => (bool) $package->branding_allowed,
            'activates_immediately' => (bool) ($package->activates_immediately ?? true),
        ];
    }

    protected function buildPlaceholderReplacements(Package $package): array
    {
        $locale = app()->getLocale();

        return [
            '{{max_photos}}' => $this->formatCount($package->max_photos, [
                'de' => 'unbegrenzt viele',
                'en' => 'unlimited',
            ]),
            '{{max_guests}}' => $this->formatCount($package->max_guests, [
                'de' => 'beliebig viele',
                'en' => 'any number of',
            ]),
            '{{max_tasks}}' => $this->formatCount($package->max_tasks, [
                'de' => 'individuelle',
                'en' => 'custom',
            ]),
            '{{max_events_per_year}}' => $this->formatCount($package->max_events_per_year, [
                'de' => 'unbegrenzte',
                'en' => 'unlimited',
            ]),
            '{{gallery_duration}}' => $this->formatGalleryDuration($package->gallery_days),
        ];
    }

    protected function applyPlaceholders(string $template, array $replacements): string
    {
        if ($template === '') {
            return $template;
        }

        return str_replace(array_keys($replacements), array_values($replacements), $template);
    }

    protected function formatCount(?int $value, array $fallbackByLocale): string
    {
        $locale = app()->getLocale();

        if ($value === null) {
            return $fallbackByLocale[$locale] ?? reset($fallbackByLocale) ?? '';
        }

        $decimal = $locale === 'de' ? ',' : '.';
        $thousands = $locale === 'de' ? '.' : ',';

        return number_format($value, 0, $decimal, $thousands);
    }

    protected function formatGalleryDuration(?int $days): string
    {
        $locale = app()->getLocale();

        if (! $days || $days <= 0) {
            return $locale === 'en' ? 'permanent' : 'dauerhaft';
        }

        if ($days % 30 === 0) {
            $months = (int) ($days / 30);
            if ($locale === 'en') {
                return $months === 1 ? '1 month' : $months.' months';
            }

            return $months === 1 ? '1 Monat' : $months.' Monate';
        }

        return $locale === 'en' ? $days.' days' : $days.' Tage';
    }

    protected function normaliseFeatures(mixed $features): array
    {
        if (is_string($features)) {
            $decoded = json_decode($features, true);
            if (json_last_error() === JSON_ERROR_NONE) {
                $features = $decoded;
            }
        }

        if (! is_array($features)) {
            return [];
        }

        $list = [];
        foreach ($features as $key => $value) {
            if (is_string($value)) {
                $list[] = $value;

                continue;
            }

            if (is_string($key) && (bool) $value) {
                $list[] = $key;
            }
        }

        return array_values(array_unique(array_filter($list, fn ($item) => is_string($item) && $item !== '')));
    }

    protected function resolveTranslation(mixed $value, string $fallback, string $locale): string
    {
        if (is_string($value)) {
            $decoded = json_decode($value, true);
            if (json_last_error() === JSON_ERROR_NONE) {
                $value = $decoded;
            }
        }

        if (is_array($value)) {
            return trim((string) ($value[$locale] ?? $value['en'] ?? $value['de'] ?? $fallback));
        }

        return trim((string) ($value ?? $fallback));
    }
}
