<?php

namespace App\Nova\Forms;

use Closure;
use Illuminate\Support\Str;

class NovaForm
{
    /**
     * Fill resource empty
     */
    public static function fillEmpty(): Closure
    {
        return function ($request, $model, $attribute, $requestAttribute) {};
    }

    /**
     * Fill attribute
     */
    public static function fillAttribute($key, $value): Closure
    {
        return function ($request, $model, $attribute, $requestAttribute) use ($key, $value) {
            $model->{$key} = $request->input($value);
        };
    }

    /**
     * Fill schemaless
     */
    public static function fillSchemalessField($schemalessAttribute = 'options'): Closure
    {
        return function ($request, $model, $attribute, $requestAttribute) use ($schemalessAttribute) {
            $model->{$schemalessAttribute}->set($attribute, $request->input($attribute));
        };
    }

    /**
     * Save by capitalizing firrt letter
     */
    public static function capitalize(): Closure
    {
        return function ($request, $model, $attribute, $requestAttribute) {
            $model->{$attribute} = ucfirst($request->input($attribute));
        };
    }

    /**
     * Fill the slug field
     */
    public static function fillSlug(string|array $from, ?string $resource): Closure
    {
        return function ($request, $model, $attribute, $requestAttribute) use ($from, $resource) {
            $slugSource = is_array($from) ? data_get($request, implode('.', $from)) : data_get($request, $from);
            $slug = Str::slug($slugSource);

            $query = $resource ? $resource::where('slug', $slug) : $model::where('slug', $slug);

            if ($query->exists()) {
                $slug .= Str::random(6);
            }

            $model->{$attribute} = $slug;
        };
    }

    /**
     * Fill media file name
     */
    public static function fillMediaFileName(): Closure
    {
        return fn ($originalFilename, $extension, $model) => sprintf('%s.%s', md5($originalFilename), $extension);
    }

    /**
     * Set value from cache
     */
    public static function setValueFromCache(string $dependsOnKey, string $cacheKey): Closure
    {
        return function ($field, $request, $formData) use ($dependsOnKey, $cacheKey) {
            if ($formData->{$dependsOnKey}) {
                $field->setValue(cache($cacheKey));
            }
        };
    }

    /**
     * Hash file name
     */
    public static function hashFileName(): Closure
    {
        return fn ($originalFilename, $extension, $model) => sprintf('%s.%s', md5($originalFilename), $extension);
    }
}
