<?php
declare(strict_types=1);

namespace ROITheme\Shared\Infrastructure\Services;

use ROITheme\Shared\Infrastructure\Persistence\WordPress\WordPressDefaultsRepository;

/**
 * SchemaSyncService - Sincronizar schemas JSON → BD
 *
 * RESPONSABILIDAD: Leer schemas desde archivos JSON y sincronizar con BD
 *
 * FLUJO:
 * 1. Leer archivos JSON de schemas
 * 2. Comparar con BD actual
 * 3. Agregar/Actualizar/Eliminar según diferencias
 *
 * @package ROITheme\Infrastructure\Services
 */
final class SchemaSyncService
{
    private string $schemasPath;

    public function __construct(
        private WordPressDefaultsRepository $defaultsRepository,
        string $schemasPath
    ) {
        $this->schemasPath = rtrim($schemasPath, '/');
    }

    /**
     * Sincronizar todos los schemas
     *
     * @return array ['success' => bool, 'data' => array]
     */
    public function syncAll(): array
    {
        try {
            // 1. Leer schemas desde JSON
            $schemas = $this->readSchemasFromJson();

            if (empty($schemas)) {
                return [
                    'success' => false,
                    'error' => 'No schemas found in JSON files'
                ];
            }

            // 2. Obtener schemas actuales de BD
            $currentSchemas = $this->defaultsRepository->findAll();

            // 3. Determinar cambios
            $schemaNames = array_keys($schemas);
            $currentNames = array_keys($currentSchemas);

            $toAdd = array_diff($schemaNames, $currentNames);
            $toUpdate = array_intersect($schemaNames, $currentNames);
            $toDelete = array_diff($currentNames, $schemaNames);

            // 4. Aplicar cambios
            $added = [];
            $updated = [];
            $deleted = [];

            foreach ($toAdd as $name) {
                $this->defaultsRepository->saveDefaults($name, $schemas[$name]);
                $added[] = $name;
            }

            foreach ($toUpdate as $name) {
                $this->defaultsRepository->updateDefaults($name, $schemas[$name]);
                $updated[] = $name;
            }

            foreach ($toDelete as $name) {
                $this->defaultsRepository->deleteDefaults($name);
                $deleted[] = $name;
            }

            return [
                'success' => true,
                'data' => [
                    'added' => $added,
                    'updated' => $updated,
                    'deleted' => $deleted
                ]
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Sincronizar un componente específico
     *
     * @param string $componentName
     * @return array
     */
    public function syncComponent(string $componentName): array
    {
        try {
            $schemas = $this->readSchemasFromJson();

            if (!isset($schemas[$componentName])) {
                return [
                    'success' => false,
                    'error' => "Schema not found for: {$componentName}"
                ];
            }

            $this->defaultsRepository->saveDefaults($componentName, $schemas[$componentName]);

            return [
                'success' => true,
                'data' => ['synced' => $componentName]
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Leer schemas desde archivos JSON
     *
     * @return array Array asociativo [componentName => schema]
     */
    private function readSchemasFromJson(): array
    {
        $schemas = [];

        // Escanear directorio de schemas
        $files = glob($this->schemasPath . '/*.json');

        if (empty($files)) {
            throw new \RuntimeException("No schema files found in: {$this->schemasPath}");
        }

        foreach ($files as $file) {
            $content = file_get_contents($file);
            $schema = json_decode($content, true);

            if (json_last_error() !== JSON_ERROR_NONE) {
                throw new \RuntimeException('Invalid JSON in file ' . basename($file) . ': ' . json_last_error_msg());
            }

            if (!isset($schema['component_name'])) {
                throw new \RuntimeException('Missing component_name in schema file: ' . basename($file));
            }

            $componentName = $schema['component_name'];
            $schemas[$componentName] = $schema;
        }

        return $schemas;
    }
}
