<?php

declare(strict_types=1);

namespace Autogedal\FeedMonitor\Model\Firebear;

use Magento\Framework\App\Filesystem\DirectoryList;

/**
 * Reads the log Firebear writes for one import (var/log/firebear/<file>.log): rows checked / invalid, rows imported /
 * updated, and the last error lines.
 */
class ImportLog
{
    private const MAX_ERRORS = 5;

    public function __construct(
        private readonly DirectoryList $directoryList
    ) {
    }

    /**
     * @param string $file the "file" of the history row (e.g. "22-1792681016")
     * @return array{found: bool, checked: int|null, invalid: int|null, imported: int|null, updated: int|null, errors: string[]}
     */
    public function read(string $file): array
    {
        $result = ['found' => false, 'checked' => null, 'invalid' => null, 'imported' => null, 'updated' => null, 'errors' => []];
        $path = $this->directoryList->getPath(DirectoryList::LOG) . '/firebear/' . basename($file) . '.log';
        if ($file === '' || !is_readable($path)) {
            return $result;
        }

        $result['found'] = true;
        $handle = fopen($path, 'r');
        try {
            while (($line = fgets($handle)) !== false) {
                $this->parseLine($line, $result);
            }
        } finally {
            fclose($handle);
        }

        return $result;
    }

    /**
     * Lines look like: <span class="console-error">2026-11-04 10:42:52 : message</span>
     */
    public function parseLine(string $line, array &$result): void
    {
        $level = preg_match('/class="console-(\w+)"/', $line, $match) ? strtolower($match[1]) : '';
        $text = trim(html_entity_decode(strip_tags($line)));
        $text = (string)preg_replace('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\s*:\s*/', '', $text);
        if ($text === '') {
            return;
        }

        if (preg_match('/Checked rows: (\d+).*?invalid rows: (\d+)/i', $text, $match)) {
            $result['checked'] = (int)$match[1];
            $result['invalid'] = (int)$match[2];
        } elseif (preg_match('/^Imported: (\d+) rows/i', $text, $match)) {
            $result['imported'] = (int)$match[1];
        } elseif (preg_match('/^Updated: (\d+) rows/i', $text, $match)) {
            $result['updated'] = (int)$match[1];
        }
        if ($level === 'error' || $level === 'critical') {
            $result['errors'][] = mb_substr($text, 0, 300);
            $result['errors'] = array_slice($result['errors'], -self::MAX_ERRORS);
        }
    }
}
