<?php
declare(strict_types=1);

namespace Autogedal\EanTools\ViewModel;

use Autogedal\EanTools\Model\ByteSize;
use Autogedal\EanTools\Model\ResultStorage;
use Autogedal\EanTools\Model\Tool\RunLabel;
use Magento\Backend\Model\UrlInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\View\Element\Block\ArgumentInterface;
use Throwable;

class RunResult implements ArgumentInterface
{
    private ?array $manifest = null;
    private ?string $error = null;

    public function __construct(
        private readonly ResultStorage $storage,
        private readonly RequestInterface $request,
        private readonly UrlInterface $urlBuilder,
        private readonly RunLabel $runLabel,
        private readonly ByteSize $byteSize
    ) {
    }

    public function getRunId(): string
    {
        return (string)$this->request->getParam('run', '');
    }

    public function getManifest(): array
    {
        if ($this->manifest === null) {
            try {
                $this->manifest = $this->storage->readManifest($this->getRunId());
            } catch (Throwable $exception) {
                $this->manifest = [];
                $this->error = $exception->getMessage();
            }
        }

        return $this->manifest;
    }

    public function getError(): ?string
    {
        $this->getManifest();

        return $this->error;
    }

    public function getToolTitle(): string
    {
        return $this->runLabel->getTitle((string)($this->getManifest()['tool'] ?? ''));
    }

    public function getBackUrl(): string
    {
        $path = match ($this->getManifest()['tool'] ?? '') {
            'validator' => 'autogedal_ean/validate/index',
            'missing' => 'autogedal_ean/missing/index',
            default => 'autogedal_ean/index/index',
        };

        return $this->urlBuilder->getUrl($path);
    }

    public function getSummary(): array
    {
        return (array)($this->getManifest()['summary'] ?? []);
    }

    public function getFiles(): array
    {
        return (array)($this->getManifest()['files'] ?? []);
    }

    public function getNotes(): array
    {
        return (array)($this->getManifest()['notes'] ?? []);
    }

    public function getStatus(): string
    {
        return (string)($this->getManifest()['status'] ?? ResultStorage::STATUS_COMPLETE);
    }

    public function getStatusMessage(): ?string
    {
        return match ($this->getStatus()) {
            ResultStorage::STATUS_QUEUED => (string)__(
                'The request is queued. Magento cron will usually process it within one minute.'
            ),
            ResultStorage::STATUS_PROCESSING => (string)__(
                'The file is being generated. Refresh the page in a few moments.'
            ),
            ResultStorage::STATUS_FAILED => (string)(
                $this->getManifest()['error'] ?? __('The file could not be generated.')
            ),
            default => null,
        };
    }

    public function isPending(): bool
    {
        return in_array(
            $this->getStatus(),
            [ResultStorage::STATUS_QUEUED, ResultStorage::STATUS_PROCESSING],
            true
        );
    }

    public function hasFailed(): bool
    {
        return $this->getStatus() === ResultStorage::STATUS_FAILED;
    }

    public function getDownloadUrl(string $fileName): string
    {
        return $this->urlBuilder->getUrl('autogedal_ean/download/index', [
            'run' => $this->getRunId(),
            'file' => $fileName,
        ]);
    }

    public function getRefreshUrl(): string
    {
        return $this->urlBuilder->getUrl('autogedal_ean/result/index', ['run' => $this->getRunId()]);
    }

    public function formatSize(int $bytes): string
    {
        return $this->byteSize->format($bytes);
    }
}
