<?php
/**
 * Block Registry Model
 * Core model for reusable content blocks (ACF-like)
 */
namespace Mtc\Modules\BlockRegistry\Models;

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

class BlockRegistry extends Model
{
    protected $table = 'block_registry';

    protected $fillable = [
        'uuid',
        'name',
        'slug',
        'description',
        'category_id',
        'icon',
        'preview_image',
        'template',
        'is_system',
        'is_active',
        'version',
        'order_index',
    ];

    protected $casts = [
        'is_system' => 'boolean',
        'is_active' => 'boolean',
        'version' => 'integer',
        'order_index' => 'integer',
        'category_id' => 'integer',
    ];

    /**
     * Get the block's category
     */
    public function category(): BelongsTo
    {
        return $this->belongsTo(BlockRegistryCategory::class, 'category_id');
    }

    /**
     * Get top-level fields for this block (excludes sub-fields)
     */
    public function fields(): HasMany
    {
        return $this->hasMany(BlockRegistryField::class, 'block_id')
            ->whereNull('parent_field_id')
            ->orderBy('order_index');
    }

    /**
     * Get all fields including sub-fields
     */
    public function allFields(): HasMany
    {
        return $this->hasMany(BlockRegistryField::class, 'block_id')
            ->orderBy('order_index');
    }

    /**
     * Get template assignments for this block
     */
    public function templateAssignments(): HasMany
    {
        return $this->hasMany(BlockRegistryTemplateAssignment::class, 'block_id');
    }

    /**
     * Get templates this block is assigned to
     */
    public function getTemplatesAttribute(): array
    {
        return $this->templateAssignments()
            ->pluck('template_name')
            ->toArray();
    }

    /**
     * Get count of entity blocks using this block
     */
    public function getUsageCountAttribute(): int
    {
        return EntityBlock::where('block_id', $this->id)->count();
    }

    /**
     * Get the full template path for Twig rendering
     * Normalizes the path to ensure it starts with 'includes/'
     */
    public function getTemplatePath(): ?string
    {
        if (empty($this->template)) {
            return null;
        }

        $path = $this->template;

        // Normalize path - ensure it starts with 'includes/'
        if (!str_starts_with($path, 'includes/')) {
            $path = 'includes/' . $path;
        }

        return $path;
    }

    /**
     * Check if this block has a rendering template configured
     */
    public function hasTemplate(): bool
    {
        return !empty($this->template);
    }

    /**
     * Convert block structure to pagedata format (for Pagedata::merge)
     */
    public function toPagedataStructure(): array
    {
        $fields = $this->fields()->get();

        $items = [[
            'order' => 0,
            'data' => $fields->map(function ($field, $index) {
                return array_filter([
                    'name' => $field->name,
                    'type' => $field->type,
                    'order' => $field->order_index,
                    'required' => $field->required ? 1 : 0,
                    'css_class' => $field->css_class,
                    'settings' => $field->settings,
                    'options' => $field->options,
                    'regex' => $field->regex,
                    'mime' => $field->mime,
                    'info' => $field->info,
                ], fn($v) => $v !== null && $v !== '');
            })->values()->toArray(),
        ]];

        return [
            [
                'name' => $this->name,
                'type' => 'text',
                'order' => 0,
                'allow_more' => $this->hasRepeaterFields() ? 1 : 0,
                'items' => $items,
            ]
        ];
    }

    /**
     * Check if block has repeater fields
     */
    public function hasRepeaterFields(): bool
    {
        return $this->fields()->where('is_repeater', true)->exists();
    }

    /**
     * Export block structure to JSON (compatible with existing structure files)
     */
    public function toStructureJson(): string
    {
        return json_encode([
            'action' => 'add_pagedata_structure',
            'pagedata' => $this->toPagedataStructure(),
        ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
    }

    /**
     * Get blocks available for a specific template
     */
    public static function getAvailableForTemplate(string $templateName): \Illuminate\Database\Eloquent\Collection
    {
        return self::where('is_active', true)
            ->where(function ($query) use ($templateName) {
                // Blocks explicitly assigned to this template
                $query->whereHas('templateAssignments', function ($q) use ($templateName) {
                    $q->where('template_name', $templateName);
                });
            })
            ->with(['category', 'fields'])
            ->orderBy('order_index')
            ->get();
    }

    /**
     * Check if block can be deleted (not in use)
     */
    public function canBeDeleted(): bool
    {
        if ($this->is_system) {
            return false;
        }
        return EntityBlock::where('block_id', $this->id)->count() === 0
            && DB::table('page_list_block_links')->where('block_id', $this->id)->count() === 0;
    }

    /**
     * Generate slug from name
     */
    public static function generateSlug(string $name): string
    {
        return Str::slug($name);
    }

    /**
     * Boot method for model events
     */
    protected static function boot(): void
    {
        parent::boot();

        static::creating(function ($block) {
            if (empty($block->uuid)) {
                $block->uuid = (string) Str::uuid();
            }
            if (empty($block->slug)) {
                $block->slug = self::generateSlug($block->name);
            }
        });

        static::deleting(function ($block) {
            // Cascade delete fields
            $block->allFields()->delete();
            // Cascade delete template assignments
            $block->templateAssignments()->delete();
        });
    }
}
