<?php

declare(strict_types=1);

namespace App\CreatorsApi\Model;

/**
 * Metadati di un report restituito da ListReports.
 *
 * Il nome file segue la forma `<account>-<family>-<YYYYMMDD>.tsv.gz`; la data del
 * report si ricava dal suffisso `YYYYMMDD`. Vedi la knowledge base delle famiglie
 * di report in docs/en/api-reference/operations/list-reports.md.
 */
final class ReportMetadata
{
    public string $filename = '';
    public string $md5 = '';
    public float $size = 0.0;
    public string $lastModified = '';

    public function __construct(array $data)
    {
        $this->filename = (string) ($data['filename'] ?? '');
        $this->md5 = (string) ($data['md5'] ?? '');
        $this->size = (float) ($data['size'] ?? 0);
        $this->lastModified = (string) ($data['lastModified'] ?? '');
    }

    public static function fromApiData(array $data): self
    {
        return new self($data);
    }

    /**
     * Costruisce la lista di metadati a partire dalla risposta grezza di ListReports.
     *
     * @param array $response Decodifica JSON di ListReports: { reports: [...] }.
     *
     * @return self[]
     */
    public static function fromListResponse(array $response): array
    {
        $reports = $response['reports'] ?? [];

        return array_map(
            static fn (array $report): self => self::fromApiData($report),
            array_values($reports)
        );
    }

    /**
     * Famiglia del report ricavata dal nome file (es. "tracking_id", "category").
     *
     * I marker si sovrappongono: va confrontata prima la famiglia piu' specifica
     * (linked_product_tracking prima di linked_product, tracking_id prima di
     * tracking, bounty_earnings prima di bounty).
     */
    public function family(): ?string
    {
        $families = [
            'linked_product_tracking',
            'linked_product',
            'bounty_earnings',
            'bounty',
            'tracking_id',
            'tracking',
            'category',
            'earnings',
            'orders',
            'subtag',
        ];

        foreach ($families as $family) {
            if (str_contains($this->filename, '-' . $family . '-')) {
                return $family;
            }
        }

        return null;
    }

    /**
     * Data del report (YYYY-MM-DD) estratta dal suffisso YYYYMMDD del nome file.
     */
    public function reportDate(): ?string
    {
        if (preg_match('/(\d{4})(\d{2})(\d{2})\.tsv\.gz$/', $this->filename, $m) === 1) {
            return sprintf('%s-%s-%s', $m[1], $m[2], $m[3]);
        }

        return null;
    }

    public function toArray(): array
    {
        return [
            'filename' => $this->filename,
            'md5' => $this->md5,
            'size' => $this->size,
            'lastModified' => $this->lastModified,
            'family' => $this->family(),
            'reportDate' => $this->reportDate(),
        ];
    }
}
