<?php

namespace App\Domains\Tenant\Resources\AdminApp;

use App\Domains\Attachable\Models\Attachment;
use App\Domains\Attachable\Models\AttachmentCrop;
use App\Domains\Tenant\Models\Tenant;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

/**
 * @mixin Tenant
 */
class WebsiteExtrasResource extends JsonResource
{
    /**
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        $websiteExtras = $this->websiteExtras->keyBy(
            fn ($extra) => $extra->websiteTypeExtra->codigo
        );

        return [
            'website_type' => $this->websiteType ? [
                'codigo' => $this->websiteType->codigo,
                'nombre' => $this->websiteType->nombre,
            ] : null,
            'definitions' => $this->websiteType?->extras
                ->mapWithKeys(fn ($definition) => [
                    $definition->codigo => [
                        'codigo' => $definition->codigo,
                        'nombre' => $definition->nombre,
                        'descripcion' => $definition->descripcion,
                        'is_required' => $definition->is_required,
                        'is_enabled' => $websiteExtras
                            ->get($definition->codigo)?->is_enabled,
                        'request_rules' => $definition->config_schema['request_rules'] ?? [],
                    ],
                ]) ?? [],
            'extras' => $websiteExtras->mapWithKeys(fn ($extra) => [
                $extra->websiteTypeExtra->codigo => $this->formatConfig(
                    $extra->resolvedConfig(),
                    fn (Attachment $attachment): string => $attachment->key
                ),
            ]),
            'resolved_extras' => $websiteExtras->mapWithKeys(fn ($extra) => [
                $extra->websiteTypeExtra->codigo => $this->formatResolvedConfig($extra),
            ]),
        ];
    }

    private function formatResolvedConfig(mixed $extra): mixed
    {
        $config = $extra->resolvedConfig();

        if (
            $extra->websiteTypeExtra->codigo === 'heroConfig'
            && is_array($config)
            && ($config['background_image_id'] ?? null) instanceof Attachment
        ) {
            $attachment = $config['background_image_id'];
            $config['background_image_id'] = $this->formatHeroAttachment($attachment);
        }

        return $this->formatConfig(
            $config,
            fn (Attachment $attachment): string => $attachment->getTemporaryUrl(1440)
        );
    }

    /**
     * @return array{url: string, crops: array<string, array<string, array<string, float>>>}
     */
    private function formatHeroAttachment(Attachment $attachment): array
    {
        $fullRange = ['start_percentage' => 0.0, 'end_percentage' => 100.0];
        $crops = $attachment->cropVariants->keyBy('variant');

        return [
            'url' => $attachment->getTemporaryUrl(1440),
            'crops' => collect(AttachmentCrop::VARIANTS)->mapWithKeys(
                function (string $variant) use ($crops, $fullRange): array {
                    $crop = $crops->get($variant);

                    return [$variant => [
                        'crop_horizontal' => $crop?->crop_horizontal ?? $fullRange,
                        'crop_vertical' => $crop?->crop_vertical ?? $fullRange,
                    ]];
                }
            )->all(),
        ];
    }

    private function formatConfig(mixed $value, callable $formatAttachment): mixed
    {
        if ($value instanceof Attachment) {
            return $formatAttachment($value);
        }

        if (! is_array($value)) {
            return $value;
        }

        return array_map(
            fn (mixed $item): mixed => $this->formatConfig($item, $formatAttachment),
            $value
        );
    }
}
