<?php

declare(strict_types=1);

namespace App\Filament\Pages;

use App\Filament\Concerns\InteractsWithDberpPermissions;
use App\Filament\Pages\Concerns\ManagesDberpSystemProfileForm;
use App\Models\DberpDictionaryType;
use App\Models\DberpWarehouse;
use App\Services\DberpPermissionService;
use BackedEnum;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Toggle;
use Filament\Pages\Page;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Illuminate\Contracts\Support\Htmlable;
use UnitEnum;

final class BusinessParametersSettingsPage extends Page
{
    use InteractsWithDberpPermissions;
    use ManagesDberpSystemProfileForm;

    protected static ?string $slug = 'system-business-parameters';

    protected static ?int $navigationSort = 20;

    public static function getNavigationGroup(): string|UnitEnum|null
    {
        return __('dberp.nav.system');
    }

    public static function getNavigationLabel(): string
    {
        return __('dberp.labels.business_parameters');
    }

    public static function getNavigationIcon(): string|BackedEnum|Htmlable|null
    {
        return null;
    }

    public static function canAccess(): bool
    {
        return self::allowsPermission(DberpPermissionService::VIEW_SYSTEM_SETTINGS);
    }

    public function getTitle(): string|Htmlable
    {
        return __('dberp.labels.business_parameters');
    }

    /**
     * @return list<string>
     */
    protected function profileFieldNames(): array
    {
        return [
            'allow_negative_stock',
            'default_warehouse_id',
            'default_source_type_item_id',
            'document_void_policy',
            'receipt_over_limit_policy',
            'payment_over_limit_policy',
            'allow_settlement_on_closed_document',
            'settlement_void_policy',
            'safety_stock_alert_enabled',
        ];
    }

    protected function profileAuditAction(): string
    {
        return 'dberp.system_profile.business_updated';
    }

    /**
     * @param  array<string, mixed>  $data
     * @return array<string, mixed>
     */
    protected function mutateFormDataBeforeSave(array $data): array
    {
        if (array_key_exists('default_warehouse_id', $data) && $data['default_warehouse_id'] === '') {
            $data['default_warehouse_id'] = null;
        }

        return $data;
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                Section::make(__('dberp.sections.inventory_and_doc'))
                    ->schema([
                        Toggle::make('allow_negative_stock')
                            ->label(__('dberp.fields.allow_negative_stock'))
                            ->helperText(__('dberp.hints.allow_negative_stock')),
                        Select::make('default_warehouse_id')
                            ->label(__('dberp.fields.default_warehouse'))
                            ->options(fn (): array => DberpWarehouse::query()
                                ->where('is_enabled', true)
                                ->orderBy('sort_order')
                                ->orderBy('id')
                                ->pluck('name', 'id')
                                ->all())
                            ->helperText(__('dberp.hints.default_warehouse'))
                            ->searchable()
                            ->preload()
                            ->nullable(),
                        Select::make('default_source_type_item_id')
                            ->label(__('dberp.fields.default_source_type'))
                            ->helperText(__('dberp.hints.default_source_type'))
                            ->options(function (): array {
                                $type = DberpDictionaryType::query()->where('code', 'source_type')->first();
                                if ($type === null) {
                                    return [];
                                }

                                return $type->items()
                                    ->where('is_enabled', true)
                                    ->orderBy('sort_order')
                                    ->orderBy('id')
                                    ->pluck('label', 'id')
                                    ->all();
                            })
                            ->searchable()
                            ->preload()
                            ->nullable(),
                        Select::make('document_void_policy')
                            ->label(__('dberp.fields.document_void_policy'))
                            ->options(__('dberp.options.document_void_policy'))
                            ->helperText(__('dberp.hints.document_void_policy'))
                            ->required(),
                        Select::make('receipt_over_limit_policy')
                            ->label(__('dberp.fields.receipt_over_limit_policy'))
                            ->options(__('dberp.options.receipt_over_limit_policy'))
                            ->required(),
                        Select::make('payment_over_limit_policy')
                            ->label(__('dberp.fields.payment_over_limit_policy'))
                            ->options(__('dberp.options.payment_over_limit_policy'))
                            ->required(),
                        Toggle::make('allow_settlement_on_closed_document')
                            ->label(__('dberp.fields.allow_settlement_on_closed_document'))
                            ->helperText(__('dberp.hints.allow_settlement_on_closed_document')),
                        Select::make('settlement_void_policy')
                            ->label(__('dberp.fields.settlement_void_policy'))
                            ->options(__('dberp.options.settlement_void_policy'))
                            ->helperText(__('dberp.hints.settlement_void_policy'))
                            ->required(),
                        Toggle::make('safety_stock_alert_enabled')
                            ->label(__('dberp.fields.safety_stock_alert_enabled'))
                            ->helperText(__('dberp.hints.safety_stock_alert')),
                    ])
                    ->columns(1),
            ]);
    }
}
