<?php
declare(strict_types=1);

namespace PpPhp\Core\Designer\Build;

use PpPhp\Core\Designer\Build\Contracts\BuildManifest;
use PpPhp\Core\Designer\Build\Contracts\ExportPackage;

final class DesignerExportRuntime
{
    private array $operations = [];

    public function export(BuildManifest $manifest, string $exportRoot = 'build'): ExportPackage
    {
        $applicationId = $manifest->applicationId();
        $exportPath = rtrim($exportRoot, '/') . '/' . $applicationId;
        $writePlan = [];

        foreach ($manifest->artifacts() as $artifact) {
            $writePlan[] = [
                'path' => $exportPath . '/' . ltrim($artifact->path(), '/'),
                'type' => $artifact->type(),
                'bytes' => $artifact->bytes(),
                'checksum' => $artifact->checksum(),
            ];
        }

        $package = ExportPackage::create(
            $applicationId,
            $manifest,
            $exportPath,
            $applicationId . '-export.zip',
            $writePlan,
            ['exportedAt' => date('c'), 'runtime' => 'designer-export']
        );

        $this->record('export', ['applicationId' => $applicationId, 'artifacts' => count($writePlan)]);

        return $package;
    }

    public function exportCrudApplication(string $appId, string $title, array $tables, string $exportRoot = 'build'): ExportPackage
    {
        $manifest = (new DesignerBuildRuntime())->buildCrudApplication($appId, $title, $tables);
        return $this->export($manifest, $exportRoot);
    }

    public function stats(ExportPackage $package): array
    {
        $row = $package->toArray();

        return [
            'operations' => count($this->operations),
            'packages' => 1,
            'artifacts' => $row['artifacts'] ?? 0,
            'writePlan' => count((array) ($row['writePlan'] ?? [])),
            'archiveName' => $row['archiveName'] ?? '',
        ];
    }

    public function operations(): array { return $this->operations; }

    private function record(string $operation, array $payload): void
    {
        $this->operations[] = ['operation' => $operation, 'payload' => $payload, 'createdAt' => date('c')];
    }
}
