<?php

namespace App\PageBuilder;

abstract class PageComponent
{
    abstract public function key(): string;
    abstract public function category(): string;     // 'layout' | 'content' | 'marketing' | 'dynamic'
    abstract public function label(): string;
    abstract public function icon(): string;
    abstract public function schema(): array;
    abstract public function defaults(): array;
    abstract public function render(array $data, array $options): string;

    public function isDynamic(): bool
    {
        return $this->category() === 'dynamic';
    }

    /**
     * Tüm component'lerde ortak options. Wrapper div'inde uygulanır
     * (margin_top / margin_bottom) ya da metadata olarak (anchor / css_class).
     * Component-specific options bunların ÜSTÜNE eklenir.
     */
    public function commonOptions(): array
    {
        return [
            'margin_top'    => ['type' => 'select', 'label' => 'Üst boşluk',  'options' => ['none', 'sm', 'md', 'lg', 'xl'], 'default' => 'none'],
            'margin_bottom' => ['type' => 'select', 'label' => 'Alt boşluk',  'options' => ['none', 'sm', 'md', 'lg', 'xl'], 'default' => 'none'],
            'anchor'        => ['type' => 'text',   'label' => 'Anchor ID (opsiyonel)'],
            'css_class'     => ['type' => 'text',   'label' => 'Ek CSS class (opsiyonel)'],
        ];
    }

    /**
     * Component'in storefront tarafında ihtiyaç duyduğu JS/CSS asset'leri.
     * Raw HTML döndürür (script/link/style tag'leri); PageRenderer @push('scripts')'e ekler.
     * Boş dönen component'ler hiçbir şey eklemiyor — opt-in pattern.
     *
     * Örnek: DomainSearchComponent burada window.apiDomainSearchUrl + @vite tag'ini döndürür.
     */
    public function storefrontAssetsHtml(): string
    {
        return '';
    }

    public function jsBlockDefinition(): array
    {
        $schema = $this->schema();
        $schema['options'] = array_merge($this->commonOptions(), $schema['options'] ?? []);

        $defaults = $this->defaults();
        $defaultOpts = $defaults['options'] ?? [];
        foreach ($this->commonOptions() as $optKey => $optDef) {
            if (! array_key_exists($optKey, $defaultOpts) && array_key_exists('default', $optDef)) {
                $defaultOpts[$optKey] = $optDef['default'];
            }
        }
        $defaults['options'] = $defaultOpts;

        return [
            'id'       => $this->key(),
            'label'    => $this->label(),
            'category' => $this->category(),
            'icon'     => $this->icon(),
            'schema'   => $schema,
            'defaults' => $defaults,
        ];
    }
}
