<?php
/**
 * Block Registry Version Model
 * Audit log for block structure changes (for rollback/history)
 */
namespace Mtc\Modules\BlockRegistry\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\DB;

class BlockRegistryVersion extends Model
{
    protected $table = 'block_registry_versions';

    public $timestamps = false;

    protected $fillable = [
        'block_id',
        'version',
        'structure',
        'changed_by',
        'change_description',
        'created_at',
    ];

    protected $casts = [
        'block_id' => 'integer',
        'version' => 'integer',
        'structure' => 'array',
        'changed_by' => 'integer',
        'created_at' => 'datetime',
    ];

    /**
     * Get the block
     */
    public function block(): BelongsTo
    {
        return $this->belongsTo(BlockRegistry::class, 'block_id');
    }

    /**
     * Get the user who made the change
     */
    public function changedByUser(): ?object
    {
        if (!$this->changed_by) {
            return null;
        }
        // Return basic user info - adjust based on your user model
        return \DB::table('users')->where('id', $this->changed_by)->first();
    }

    /**
     * Create a snapshot of a block's current structure
     */
    public static function createSnapshot(
        BlockRegistry $block,
        ?int $userId = null,
        ?string $description = null
    ): self {
        return self::create([
            'block_id' => $block->id,
            'version' => $block->version ?? 1,
            'structure' => [
                'name' => $block->name,
                'slug' => $block->slug,
                'description' => $block->description,
                'fields' => $block->fields->map(function ($field) {
                    return $field->toPagedataFormat();
                })->toArray(),
            ],
            'changed_by' => $userId,
            'change_description' => $description,
            'created_at' => now(),
        ]);
    }

    /**
     * Get the latest version for a block
     */
    public static function getLatestForBlock(int $blockId): ?self
    {
        return self::where('block_id', $blockId)
            ->orderBy('version', 'desc')
            ->first();
    }

    /**
     * Compare two versions and return differences
     */
    public static function compareVersions(self $oldVersion, self $newVersion): array
    {
        $oldFields = collect($oldVersion->structure['fields'] ?? [])
            ->keyBy('name');
        $newFields = collect($newVersion->structure['fields'] ?? [])
            ->keyBy('name');

        return [
            'added' => $newFields->diffKeys($oldFields)->keys()->toArray(),
            'removed' => $oldFields->diffKeys($newFields)->keys()->toArray(),
            'modified' => $newFields->filter(function ($field, $name) use ($oldFields) {
                if (!$oldFields->has($name)) {
                    return false;
                }
                return json_encode($field) !== json_encode($oldFields[$name]);
            })->keys()->toArray(),
        ];
    }

    /**
     * Restore a block to this version
     */
    public function restore(): bool
    {
        $block = $this->block;
        if (!$block) {
            return false;
        }

        return DB::transaction(function () use ($block) {
            // Delete current fields (including sub-fields)
            $block->allFields()->delete();

            // Restore fields from snapshot
            foreach ($this->structure['fields'] ?? [] as $index => $fieldData) {
                BlockRegistryField::create([
                    'block_id' => $block->id,
                    'name' => $fieldData['name'],
                    'label' => $fieldData['name'],
                    'type' => $fieldData['type'] ?? 'text',
                    'order_index' => $fieldData['order'] ?? $index,
                    'required' => !empty($fieldData['required']),
                    'css_class' => $fieldData['css_class'] ?? null,
                    'settings' => $fieldData['settings'] ?? null,
                    'options' => $fieldData['options'] ?? null,
                    'regex' => $fieldData['regex'] ?? null,
                    'mime' => $fieldData['mime'] ?? null,
                    'info' => $fieldData['info'] ?? null,
                ]);
            }

            // Update block metadata
            $block->update([
                'name' => $this->structure['name'] ?? $block->name,
                'description' => $this->structure['description'] ?? $block->description,
            ]);

            // Increment version
            $block->increment('version');

            return true;
        });
    }
}
