<?php

namespace App\DTOs;

readonly class CatalogPageData
{
    /**
     * @param  list<CatalogReviewSource>  $reviewSources
     * @param  list<CatalogProduct>  $products
     */
    public function __construct(
        public string $brand,
        public string $advertiserId,
        public string $campaignId,
        public string $subcategory,
        public string $category,
        public string $updated,
        public string $heroTitle,
        public array $reviewSources,
        public array $products,
    ) {}

    /**
     * @param  array<string, mixed>  $data
     */
    public static function fromArray(array $data): self
    {
        $reviewSources = array_values(array_map(
            fn (mixed $source): CatalogReviewSource => CatalogReviewSource::fromArray(
                is_array($source) ? $source : [],
            ),
            is_array($data['review_sources'] ?? null) ? $data['review_sources'] : [],
        ));

        $products = array_values(array_map(
            fn (mixed $product): CatalogProduct => CatalogProduct::fromArray(
                is_array($product) ? $product : [],
            ),
            is_array($data['products'] ?? null) ? $data['products'] : [],
        ));

        return new self(
            brand: (string) ($data['Brand'] ?? $data['brand'] ?? ''),
            advertiserId: (string) ($data['advertiser_id'] ?? ''),
            campaignId: (string) ($data['campaign_id'] ?? ''),
            subcategory: (string) ($data['subcategory'] ?? ''),
            category: (string) ($data['category'] ?? ''),
            updated: (string) ($data['updated'] ?? ''),
            heroTitle: (string) ($data['hero_title'] ?? ''),
            reviewSources: $reviewSources,
            products: $products,
        );
    }

    public static function isComplete(?array $catalog): bool
    {
        return is_array($catalog)
            && filled($catalog['Brand'] ?? $catalog['brand'] ?? null)
            && isset($catalog['products'])
            && is_array($catalog['products'])
            && $catalog['products'] !== [];
    }

    /**
     * @return array<string, mixed>
     */
    public function toArray(): array
    {
        return [
            'Brand' => $this->brand,
            'advertiser_id' => $this->advertiserId,
            'campaign_id' => $this->campaignId,
            'subcategory' => $this->subcategory,
            'category' => $this->category,
            'updated' => $this->updated,
            'hero_title' => $this->heroTitle,
            'review_sources' => array_map(
                fn (CatalogReviewSource $source) => $source->toArray(),
                $this->reviewSources,
            ),
            'products' => array_map(
                fn (CatalogProduct $product) => $product->toArray(),
                $this->products,
            ),
        ];
    }
}
