<?php

declare(strict_types=1);

namespace App\CreatorsApi\Model;

/**
 * Wrapper minimale sull'array restituito da Creators API (GetItems).
 * Espone solo i campi effettivamente usati da AmazonItem.
 */
final class ProductItem
{
    public function __construct(private array $data)
    {
    }

    public function getAsin(): ?string
    {
        return $this->data['asin'] ?? null;
    }

    public function getTitle(): ?string
    {
        return $this->data['itemInfo']['title']['displayValue'] ?? null;
    }

    public function getBrand(): ?string
    {
        return $this->data['itemInfo']['byLineInfo']['brand']['displayValue'] ?? null;
    }

    public function getDetailPageURL(): ?string
    {
        return $this->data['detailPageURL'] ?? null;
    }

    /** Restituisce URL immagine primaria (small|medium|large, default large). */
    public function getImageUrl(string $size = 'large'): ?string
    {
        return $this->data['images']['primary'][$size]['url'] ?? null;
    }

    public function hasPrimeOffer(): bool
    {
        $listing = $this->data['offersV2']['listings'][0] ?? [];

        // Caso 1: loyaltyPoints presente (tipico Giappone)
        if (!empty($listing['loyaltyPoints'])) {
            return true;
        }

        // Caso 2: Prime esclusivo indicato nei dealDetails
        $accessType = $listing['dealDetails']['accessType'] ?? null;

        return $accessType === 'PRIME_EXCLUSIVE';
    }

    public function getPrice(): ?Price
    {
        $listing = $this->data['offersV2']['listings'][0] ?? null;
        if ($listing === null) {
            return null;
        }

        $amount = $listing['price']['money']['amount'] ?? null;
        $currency = $listing['price']['money']['currency'] ?? null;

        if ($amount === null || $currency === null) {
            // fallback best-effort su displayAmount
            $display = $listing['price']['displayAmount'] ?? null;
            if ($display !== null && is_string($display)) {
                if (preg_match('/([0-9]+[\\.,]?[0-9]*)/', $display, $m)) {
                    $amount = (float) str_replace(',', '.', $m[1]);
                }
            }
        }

        if ($amount === null || $currency === null) {
            return null;
        }

        $available = $this->isListingAvailable($listing);

        return new Price((float) $amount, (string) $currency, $available);
    }

    public function getOriginalPrice(): ?Price
    {
        $listing = $this->data['offersV2']['listings'][0] ?? null;
        if ($listing === null) {
            return null;
        }

        // Path corretto: price.savingBasis.money
        $amount = $listing['price']['savingBasis']['money']['amount'] ?? null;
        $currency = $listing['price']['savingBasis']['money']['currency'] ?? null;

        if ($amount === null || $currency === null) {
            return null;
        }

        $available = $this->isListingAvailable($listing);
        return new Price((float) $amount, (string) $currency, $available);
    }

    public function getDiscountPercentage(): ?float
    {
        return $this->data['offersV2']['listings'][0]['price']['savings']['percentage'] ?? null;
    }

    private function isListingAvailable(array $listing): bool
    {
        $type = $listing['availability']['type'] ?? null;
        if ($type === null) {
            return true;
        }
        return strtolower((string) $type) !== 'unavailable';
    }
}
