<?php

declare(strict_types=1);

namespace App\Filament\Resources\DberpInventoryExceptions\Pages;

use App\Business\Inventory\Enums\InventoryExceptionStatus;
use App\Business\Inventory\InventoryExceptionService;
use App\Filament\Resources\DberpInventoryExceptions\DberpInventoryExceptionResource;
use App\Filament\Resources\Pages\EditRecord;
use App\Filament\Support\DberpFilamentSubheading;
use App\Models\DberpInventoryException;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
use Illuminate\Contracts\Support\Htmlable;

class EditDberpInventoryException extends EditRecord
{
    protected static string $resource = DberpInventoryExceptionResource::class;

    public function getSubheading(): string|Htmlable|null
    {
        return DberpFilamentSubheading::prependBusinessHint(
            parent::getSubheading(),
            'dberp.ui.inventory_exception_edit_intro',
        );
    }

    protected function getHeaderActions(): array
    {
        return [
            Action::make('resolve')
                ->label(__('dberp.actions.resolve'))
                ->requiresConfirmation()
                ->visible(fn (DberpInventoryException $record): bool => $record->status === InventoryExceptionStatus::Open->value)
                ->authorize(fn (): bool => DberpInventoryExceptionResource::canEdit($this->getRecord()))
                ->action(function (): void {
                    app(InventoryExceptionService::class)->markResolved(
                        $this->getRecord(),
                        (string) ($this->data['handling_remark'] ?? ''),
                    );

                    Notification::make()
                        ->title((string) __('dberp.notifications.saved'))
                        ->success()
                        ->send();

                    $this->redirectToExceptionList(InventoryExceptionStatus::Resolved->value);
                }),
            Action::make('ignored')
                ->label(__('dberp.actions.ignored'))
                ->requiresConfirmation()
                ->visible(fn (DberpInventoryException $record): bool => $record->status !== InventoryExceptionStatus::Ignored->value)
                ->authorize(fn (): bool => DberpInventoryExceptionResource::canEdit($this->getRecord()))
                ->action(function (): void {
                    app(InventoryExceptionService::class)->markIgnored(
                        $this->getRecord(),
                        (string) ($this->data['handling_remark'] ?? ''),
                    );

                    Notification::make()
                        ->title((string) __('dberp.notifications.saved'))
                        ->success()
                        ->send();

                    $this->redirectToExceptionList(InventoryExceptionStatus::Ignored->value);
                }),
            Action::make('reopen')
                ->label(__('dberp.actions.reopen'))
                ->requiresConfirmation()
                ->visible(fn (DberpInventoryException $record): bool => $record->status !== InventoryExceptionStatus::Open->value)
                ->authorize(fn (): bool => DberpInventoryExceptionResource::canEdit($this->getRecord()))
                ->action(function (): void {
                    app(InventoryExceptionService::class)->reopen(
                        $this->getRecord(),
                        (string) ($this->data['handling_remark'] ?? ''),
                    );
                    $this->refreshExceptionRecordAndForm();

                    Notification::make()
                        ->title((string) __('dberp.notifications.saved'))
                        ->success()
                        ->send();
                }),
        ];
    }

    private function refreshExceptionRecordAndForm(): void
    {
        $this->record = $this->getRecord()->refresh();
        $this->fillForm();
    }

    private function redirectToExceptionList(?string $statusFilter = null): void
    {
        $parameters = [];

        if ($statusFilter !== null && $statusFilter !== '') {
            $parameters['tableFilters'] = [
                'status' => ['value' => $statusFilter],
            ];
        }

        $this->redirect(DberpInventoryExceptionResource::getUrl('index', $parameters));
    }
}
