<?php

declare(strict_types=1);

namespace Builder\Seo\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;

/**
 * Maps a composite `seo` attribute to/from three separate database columns:
 * `seo_title`, `seo_description`, and `seo_robots`.
 *
 * This allows `Field::seo()->translatable()` to use the existing form binding
 * (form.seo = { title, description, robots }) while storing each value in its
 * own queryable column rather than a JSON blob.
 *
 * @implements CastsAttributes<array{title: string|null, description: string|null, robots: string}, array{title?: string|null, description?: string|null, robots?: string|null}|null>
 */
final class SeoDataCast implements CastsAttributes
{
    /**
     * @param  array<string, mixed>  $attributes
     * @return array{title: string|null, description: string|null, robots: string}
     */
    public function get(Model $model, string $key, mixed $value, array $attributes): array
    {
        return [
            'title' => isset($attributes['seo_title']) ? (string) $attributes['seo_title'] : null,
            'description' => isset($attributes['seo_description']) ? (string) $attributes['seo_description'] : null,
            'robots' => isset($attributes['seo_robots']) ? (string) $attributes['seo_robots'] : 'index',
        ];
    }

    /**
     * @param  array{title?: string|null, description?: string|null, robots?: string|null}|null  $value
     * @return array<string, string|null>
     */
    public function set(Model $model, string $key, mixed $value, array $attributes): array
    {
        if ($value === null) {
            return [
                'seo_title' => null,
                'seo_description' => null,
                'seo_robots' => null,
            ];
        }

        return [
            'seo_title' => isset($value['title']) ? (string) $value['title'] : null,
            'seo_description' => isset($value['description']) ? (string) $value['description'] : null,
            'seo_robots' => isset($value['robots']) ? (string) $value['robots'] : 'index',
        ];
    }
}
