<?php

namespace App\Domains\Menu\Models;

use App\Domains\Authorization\Models\Role;
use App\Domains\Tenant\Models\Tenant;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Validation\ValidationException;

class Menu extends Model
{
    use HasFactory;

    public const CONTENT_TYPE_DYNAMIC = 'dynamic';

    public const CONTENT_TYPE_STATIC = 'static';

    protected $table = 'menues';

    protected $attributes = [
        'content_type' => self::CONTENT_TYPE_DYNAMIC,
    ];

    protected $fillable = [
        'code',
        'label',
        'parent_menu_code',
        'content_type',
        'static_content_schema',
        'route',
    ];

    protected function casts(): array
    {
        return [
            'static_content_schema' => 'array',
        ];
    }

    protected static function booted(): void
    {
        static::saving(function (self $menu): void {
            if (
                $menu->content_type === self::CONTENT_TYPE_STATIC
                && empty($menu->static_content_schema)
            ) {
                throw ValidationException::withMessages([
                    'static_content_schema' => __('api.menu.schema_required'),
                ]);
            }
        });
    }

    public function parent(): BelongsTo
    {
        return $this->belongsTo(self::class, 'parent_menu_code', 'code');
    }

    public function children(): HasMany
    {
        return $this->hasMany(self::class, 'parent_menu_code', 'code');
    }

    public function tenants(): BelongsToMany
    {
        return $this->belongsToMany(
            Tenant::class,
            'tenants_menues',
            'menu_code',
            'tenant_code',
            'code',
            'codigo'
        )
            ->using(TenantMenu::class)
            ->withPivot('static_content')
            ->withTimestamps();
    }

    public function roles(): BelongsToMany
    {
        return $this->belongsToMany(
            Role::class,
            'roles_menues',
            'menu_codigo',
            'rol_codigo',
            'code',
            'codigo'
        )->using(MenuRole::class);
    }
}
