<?php

namespace App\Nova\Resources\Ecommerce\Product\Product\Concerns\Variant;

use App\Jobs\Ecommerce\Product\UpdateProductRelations;
use App\Models\Ecommerce\Product\Inventory\Inventory;
use App\Nova\Forms\NovaForm;
use App\Repositories\Ecommerce\Product\NovaProductRepository;
use Ebess\AdvancedNovaMediaLibrary\Fields\Images;
use Exception;
use Illuminate\Database\Eloquent\Model;
use Laravel\Nova\Fields\Boolean;
use Laravel\Nova\Fields\Hidden;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Number;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;
use Laravel\Nova\Panel;
use Nurmuhammet\DynamicFields\DynamicFields;
use Nurmuhammet\ProductInventory\ProductInventory;

class VariantFieldsForUpdate
{
    /**
     * Get the fields for create.
     */
    public static function make(NovaRequest $request, $resource): array
    {
        $categories = $resource->parent->categories;

        return [
            ID::make()->sortable(),

            Images::make(__('Image'), 'uploads')
                ->showStatistics()
                ->setFileName(fn ($originalFilename, $extension, $model) => sprintf('%s.%s', md5($originalFilename), $extension)),

            Text::make(__('Price'), 'cost_amount')
                ->rules('required', 'numeric'),

            Text::make(__('Price without discount'), 'old_price_amount')
                ->rules('nullable', 'numeric'),

            Text::make(__('Purchase price'), 'readonly_price_amount')
                ->readonly()
                ->dependsOn(['cost_amount'], NovaProductRepository::priceAmountDependsOn($categories)),

            Hidden::make('price_amount')
                ->fillUsing(NovaForm::fillAttribute('price_amount', 'readonly_price_amount')),

            new Panel(__('Inventory'), [
                Text::make('SKU', 'sku')
                    ->rules('nullable', 'string', 'max:255'),

                Text::make(__('Barcode'), 'barcode')
                    ->rules('nullable', 'string', 'max:255'),

                ProductInventory::make(__('Inventory'), 'inventories')
                    ->rules('required')
                    ->options(Inventory::pluck('name', 'id'))
                    ->fillUsing(NovaForm::fillEmpty()),

                Hidden::make('stock')
                    ->fillUsing(function ($request, $model, $attribute, $requestAttribute) {
                        $model->{$attribute} = array_sum(array_values($request->input('inventories')));
                    }),

                Number::make(__('Security stock'), 'security_stock')
                    ->rules('nullable', 'integer'),
            ]),

            new Panel(__('Attributes'), [
                DynamicFields::make('Attributes', 'workingpn')
                    ->fillWithArrayName('properties')
                    ->fields(fn () => NovaProductRepository::attributeFieldsWithValues($categories, $resource))
                    ->fillUsing(function ($request, $model, $attribute, $requestAttribute) {
                        $properties = $request->input('properties');

                        foreach ($properties as $key => $value) {
                            try {
                                if (in_array($key, ['size', 'colour'])) {
                                    $model->{$key} = $value;
                                }
                            } catch (Exception) {
                            }
                        }
                    }),
            ]),

            new Panel(__('Shipping'), [
                Boolean::make(__('Back order'), 'back_order')
                    ->fillUsing(NovaForm::fillSchemalessField()),

                Number::make(__('Weight value'), 'weight_value')
                    ->fillUsing(NovaForm::fillSchemalessField()),

                Select::make(__('Weight unit'), 'weight_unit')
                    ->options(['kg' => 'kg'])
                    ->default('kg')
                    ->searchable()
                    ->fillUsing(NovaForm::fillSchemalessField()),

                Number::make(__('Height value'), 'height_value')
                    ->fillUsing(NovaForm::fillSchemalessField()),

                Select::make(__('Height unit'), 'height_unit')
                    ->options(['cm' => 'cm'])
                    ->default('cm')
                    ->searchable()
                    ->fillUsing(NovaForm::fillSchemalessField()),

                Number::make(__('Width value'), 'width_value')
                    ->fillUsing(NovaForm::fillSchemalessField()),

                Select::make(__('Width unit'), 'width_unit')
                    ->options(['cm' => 'cm'])
                    ->default('cm')
                    ->searchable()
                    ->fillUsing(NovaForm::fillSchemalessField()),

                Number::make(__('Depth value'), 'depth_value')
                    ->fillUsing(NovaForm::fillSchemalessField()),

                Select::make(__('Depth unit'), 'depth_unit')
                    ->options(['cm' => 'cm'])
                    ->default('cm')
                    ->searchable()
                    ->fillUsing(NovaForm::fillSchemalessField()),

                Number::make(__('Volume value'), 'volume_value')
                    ->fillUsing(NovaForm::fillSchemalessField()),

                Select::make(__('Volume unit'), 'volume_unit')
                    ->options(['kg' => 'kg'])
                    ->default('kg')
                    ->searchable()
                    ->fillUsing(NovaForm::fillSchemalessField()),
            ]),
        ];
    }

    /**
     * Register a callback to be called after the resource is updated.
     */
    public static function afterUpdate(NovaRequest $request, Model $model): void
    {
        UpdateProductRelations::dispatch(
            model: $model,
            properties: $request->input('properties'),
            inventories: $request->collect('inventories')
                ->mapWithKeys(fn ($stockValue, $inventoryID) => [$inventoryID => ['stock' => $stockValue]])
                ->toArray()
        );
    }
}
