<?php

declare(strict_types=1);

namespace App\Support\News;

final class NewsCoverImage
{
    public const MANAGED_PREFIX = 'news/covers/';

    public const VARIANTS = [
        'mobile' => [
            'width' => 400,
            'quality' => 74,
            'suffix' => 'mobile',
        ],
        'desktop' => [
            'width' => 768,
            'quality' => 76,
            'suffix' => 'desktop',
        ],
        'large' => [
            'width' => 1280,
            'quality' => 80,
            'suffix' => 'large',
        ],
    ];

    public static function isManagedPath(?string $path): bool
    {
        $trimmed = ltrim(trim((string) $path), '/');

        return $trimmed !== '' && str_starts_with($trimmed, self::MANAGED_PREFIX);
    }

    public static function normalizePath(?string $path): string
    {
        return ltrim(trim((string) $path), '/');
    }

    public static function path(string $hash): string
    {
        return sprintf(
            'news/covers/%s/%s/%s.webp',
            substr($hash, 0, 2),
            substr($hash, 2, 2),
            $hash,
        );
    }

    public static function variantPath(string $path, string $variant): string
    {
        $trimmed = self::normalizePath($path);
        $config = self::VARIANTS[$variant] ?? null;

        if ($trimmed === '' || $config === null) {
            return $trimmed;
        }

        $directory = pathinfo($trimmed, PATHINFO_DIRNAME);
        $filename = pathinfo($trimmed, PATHINFO_FILENAME);
        $extension = pathinfo($trimmed, PATHINFO_EXTENSION) ?: 'webp';

        return ($directory !== '.' ? $directory . '/' : '') . $filename . '-' . $config['suffix'] . '.' . $extension;
    }

    public static function managedPaths(string $path): array
    {
        $trimmed = self::normalizePath($path);

        if (! self::isManagedPath($trimmed)) {
            return [];
        }

        $paths = [$trimmed];

        foreach (array_keys(self::VARIANTS) as $variant) {
            $paths[] = self::variantPath($trimmed, $variant);
        }

        return array_values(array_unique($paths));
    }

    public static function url(?string $path): ?string
    {
        $trimmed = self::normalizePath($path);

        if ($trimmed === '') {
            return null;
        }

        if (str_starts_with($trimmed, 'http://') || str_starts_with($trimmed, 'https://')) {
            return $trimmed;
        }

        if (self::isManagedPath($trimmed)) {
            return rtrim((string) config('cdn.files_url', 'https://files.skinbase.org'), '/') . '/' . $trimmed;
        }

        return asset('storage/' . $trimmed);
    }

    public static function variantUrl(?string $path, string $variant): ?string
    {
        $trimmed = self::normalizePath($path);

        if (! self::isManagedPath($trimmed)) {
            return null;
        }

        return self::url(self::variantPath($trimmed, $variant));
    }

    public static function srcset(?string $path): ?string
    {
        $trimmed = self::normalizePath($path);

        if (! self::isManagedPath($trimmed)) {
            return null;
        }

        $entries = [];

        foreach (self::VARIANTS as $variant => $config) {
            $url = self::variantUrl($trimmed, $variant);

            if ($url === null) {
                continue;
            }

            $entries[] = $url . ' ' . $config['width'] . 'w';
        }

        return $entries === [] ? null : implode(', ', $entries);
    }
}