<?php

namespace App\Domain\Website\Blocks;

use App\Domain\Website\Enums\BlockCategory;

/**
 * Base class for every block the website builder can place on a page.
 *
 * Subclassing this and registering it in BlockRegistry is the ONLY step needed
 * to add a new capability to the builder — no migration, no enum edit, no
 * CHECK constraint. That is the whole point of the v3 builder.
 */
abstract class BlockType
{
    /** Stable identifier stored in website_blocks.type. Never rename in place. */
    abstract public function key(): string;

    /** Arabic label shown in the block picker. */
    abstract public function label(): string;

    abstract public function category(): BlockCategory;

    /** Heroicon name (outline set) for the block picker. */
    public function icon(): string
    {
        return 'square-3-stack-3d';
    }

    public function description(): string
    {
        return '';
    }

    /**
     * Layout variants for this block. Every variant maps to a Blade partial at
     * website.blocks.{key}.{variant}. Always include a 'default'.
     *
     * @return array<string,string>
     */
    public function variants(): array
    {
        return ['default' => 'افتراضي'];
    }

    /** @return BlockField[] */
    abstract public function fields(): array;

    /** May this block contain other blocks? */
    public function allowsChildren(): bool
    {
        return false;
    }

    /** Restrict which block types may nest inside. Null = any. */
    public function allowedChildTypes(): ?array
    {
        return null;
    }

    /** Named slots for container blocks, e.g. ['default'] or ['left','right']. */
    public function slots(): array
    {
        return ['default'];
    }

    /** Blocks that only make sense once per page (navbar, footer). */
    public function isSingleton(): bool
    {
        return false;
    }

    /** Hidden from the picker — used for internal/child-only blocks. */
    public function isHidden(): bool
    {
        return false;
    }

    /** Seed values for a freshly inserted block, derived from field defaults. */
    public function defaultData(): array
    {
        $data = [];

        foreach ($this->fields() as $field) {
            if ($field->default !== null) {
                $data[$field->key] = $field->default;
            } elseif ($field->translatable) {
                $data[$field->key] = ['ar' => '', 'en' => ''];
            }
        }

        return $data;
    }

    /**
     * Resolves the Blade partial for a variant.
     *
     * Most variants differ only in utility classes, so the common case is a
     * single `website.blocks.{key}` partial that switches on $variant itself.
     * A variant that genuinely needs different markup can override by adding
     * `website.blocks.{key}.{variant}`, which wins when present.
     */
    public function viewFor(string $variant): string
    {
        $override = "website.blocks.{$this->key()}.{$variant}";

        return view()->exists($override)
            ? $override
            : "website.blocks.{$this->key()}";
    }

    /** Validation rules for this block's data payload. */
    public function validationRules(): array
    {
        $rules = [];

        foreach ($this->fields() as $field) {
            $rules += $field->validationRules();
        }

        return $rules;
    }

    /** Flattened field lookup, including repeater sub-fields. */
    public function field(string $key): ?BlockField
    {
        foreach ($this->fields() as $field) {
            if ($field->key === $key) {
                return $field;
            }
        }

        return null;
    }
}
