<?php

namespace App\Http\Resources\Tenant;

use App\Models\WatermarkSetting;
use App\Services\Packages\PackageLimitEvaluator;
use App\Support\TenantMemberPermissions;
use App\Support\WatermarkConfigResolver;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Http\Resources\MissingValue;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\URL;

use function app;

class EventResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        $tenantId = $request->attributes->get('tenant_id');
        $showSensitive = $this->tenant_id === $tenantId;
        $settings = is_array($this->settings) ? $this->settings : [];
        $settings = $this->attachWatermarkAssetUrl($settings);
        $eventPackage = null;
        $memberPermissions = null;

        $user = $request->user();
        if ($user && $user->role === 'member') {
            $memberPermissions = TenantMemberPermissions::resolveEventPermissions($request, $this->resource);
        }

        if ($this->relationLoaded('eventPackages')) {
            $related = $this->getRelation('eventPackages');

            if (! $related instanceof MissingValue) {
                $eventPackage = $related->first();
            }
        } elseif ($this->relationLoaded('eventPackage')) {
            $related = $this->getRelation('eventPackage');

            if (! $related instanceof MissingValue) {
                $eventPackage = $related;
            }
        }

        $limitEvaluator = null;
        if ($eventPackage) {
            $limitEvaluator = app()->make(PackageLimitEvaluator::class);
        }

        $settings['watermark_removal_allowed'] = WatermarkConfigResolver::determineRemovalAllowed($this->resource);

        return [
            'id' => $this->id,
            'name' => $this->name,
            'slug' => $this->slug,
            'description' => $this->description,
            'event_date' => $this->date ? $this->date->toISOString() : null,
            'location' => $this->location,
            'max_participants' => $this->max_participants,
            'current_participants' => $showSensitive ? ($this->photos_count ?? null) : null,
            'public_url' => $settings['public_url'] ?? null,
            'custom_domain' => $showSensitive ? ($settings['custom_domain'] ?? null) : null,
            'theme_color' => $settings['theme_color'] ?? null,
            'status' => $this->status ?? 'draft',
            'is_active' => (bool) ($this->is_active ?? false),
            'features' => $settings['features'] ?? [],
            'engagement_mode' => $settings['engagement_mode'] ?? 'tasks',
            'branding' => $settings['branding'] ?? null,
            'settings' => $settings,
            'event_type_id' => $this->event_type_id,
            'event_type' => $this->whenLoaded('eventType', function () {
                return new EventTypeResource($this->eventType);
            }),
            'created_at' => $this->created_at?->toISOString(),
            'updated_at' => $this->updated_at?->toISOString(),
            'photo_count' => (int) ($this->photos_count ?? 0),
            'pending_photo_count' => isset($this->pending_photos_count) ? (int) $this->pending_photos_count : null,
            'like_count' => isset($this->likes_sum)
                ? (int) $this->likes_sum
                : $this->whenLoaded('photos', fn () => (int) $this->photos->sum('likes_count'), 0),
            'tasks_count' => isset($this->tasks_count) ? (int) $this->tasks_count : null,
            'active_invites_count' => isset($this->active_join_tokens_count) ? (int) $this->active_join_tokens_count : null,
            'total_invites_count' => isset($this->total_join_tokens_count) ? (int) $this->total_join_tokens_count : null,
            'is_public' => $this->status === 'published',
            'public_share_url' => null,
            'qr_code_url' => null,
            'package' => $eventPackage ? [
                'id' => $eventPackage->package_id,
                'name' => $eventPackage->package?->getNameForLocale(app()->getLocale()) ?? $eventPackage->package?->name,
                'price' => $eventPackage->purchased_price,
                'purchased_at' => $eventPackage->purchased_at?->toIso8601String(),
                'expires_at' => $eventPackage->gallery_expires_at?->toIso8601String(),
                'branding_allowed' => (bool) optional($eventPackage->package)->branding_allowed,
                'watermark_allowed' => (bool) optional($eventPackage->package)->watermark_allowed,
            ] : null,
            'limits' => $eventPackage && $limitEvaluator
                ? $limitEvaluator->summarizeEventPackage($eventPackage)
                : null,
            'addons' => $eventPackage ? $this->formatAddons($eventPackage) : [],
            'member_permissions' => $memberPermissions,
        ];
    }

    /**
     * @param  array<string, mixed>  $settings
     * @return array<string, mixed>
     */
    protected function attachWatermarkAssetUrl(array $settings): array
    {
        $watermark = Arr::get($settings, 'watermark');
        $base = config('watermark.base', []);
        $base = is_array($base) ? $base : [];
        $baseSetting = null;

        if (class_exists(WatermarkSetting::class) && Schema::hasTable('watermark_settings')) {
            try {
                $baseSetting = WatermarkSetting::query()->first();
            } catch (\Throwable) {
                $baseSetting = null;
            }
        }

        if ($baseSetting) {
            $base = array_merge($base, array_filter([
                'asset' => $baseSetting->asset,
                'position' => $baseSetting->position,
                'opacity' => $baseSetting->opacity,
                'scale' => $baseSetting->scale,
                'padding' => $baseSetting->padding,
                'offset_x' => $baseSetting->offset_x,
                'offset_y' => $baseSetting->offset_y,
            ], static fn ($value) => $value !== null));
        }

        if (! is_array($watermark)) {
            $watermark = [];
        }

        $mode = $watermark['mode'] ?? null;
        if (! is_string($mode) || $mode === '') {
            $mode = 'base';
            $watermark['mode'] = $mode;
        }

        if ($mode !== 'off') {
            foreach (['position', 'opacity', 'scale', 'padding', 'offset_x', 'offset_y'] as $key) {
                if (! array_key_exists($key, $watermark) && array_key_exists($key, $base)) {
                    $watermark[$key] = $base[$key];
                }
            }
        }

        $asset = $watermark['asset'] ?? null;
        if ((! is_string($asset) || $asset === '') && $mode !== 'off') {
            $asset = $base['asset'] ?? null;
            if (is_string($asset) && $asset !== '') {
                $watermark['asset'] = $asset;
            }
        }

        if (! is_string($asset) || $asset === '') {
            $settings['watermark'] = $watermark;

            return $settings;
        }

        $normalized = ltrim($asset, '/');
        if (str_starts_with($normalized, 'storage/')) {
            $normalized = substr($normalized, strlen('storage/'));
        }

        $watermark['asset_url'] = URL::temporarySignedRoute(
            'api.v1.branding.asset',
            now()->addSeconds(3600),
            ['path' => $normalized]
        );

        $settings['watermark'] = $watermark;

        return $settings;
    }

    protected function formatAddons(?\App\Models\EventPackage $eventPackage): array
    {
        if (! $eventPackage) {
            return [];
        }

        $addons = $eventPackage->relationLoaded('addons')
            ? $eventPackage->addons
            : $eventPackage->addons()->latest()->take(10)->get();

        return $addons->map(function ($addon) {
            return [
                'id' => $addon->id,
                'key' => $addon->addon_key,
                'label' => $addon->metadata['label'] ?? null,
                'status' => $addon->status,
                'price_id' => $addon->price_id,
                'transaction_id' => $addon->transaction_id,
                'extra_photos' => (int) $addon->extra_photos,
                'extra_guests' => (int) $addon->extra_guests,
                'extra_gallery_days' => (int) $addon->extra_gallery_days,
                'purchased_at' => $addon->purchased_at?->toIso8601String(),
                'metadata' => Arr::only($addon->metadata ?? [], ['price_eur']),
            ];
        })->all();
    }
}
