<?php

namespace Modules\AiAgent\Filament\Pages;

use BackedEnum;
use Filament\Actions\Action;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\Toggle;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Table;
use Illuminate\Pagination\LengthAwarePaginator;
use Modules\AiAgent\Filament\Concerns\HandlesBnfexpressErrors;
use Modules\Shared\Bnfexpress\BnfexpressAdminClient;
use Modules\Shared\Bnfexpress\Exceptions\BnfexpressApiException;
use UnitEnum;

/**
 * Version history + publish/rollback for the EV agent's system prompt.
 * Needs more than a bare table (an "active version" banner above the
 * history), so — like ManageAppSettings — it renders through a custom view
 * rather than relying purely on Filament's generated table layout.
 */
class ManageAgentInstructions extends Page implements HasTable
{
    use HandlesBnfexpressErrors;
    use InteractsWithTable;

    protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedDocumentText;

    protected static string|UnitEnum|null $navigationGroup = 'AI Agent';

    protected static ?string $navigationLabel = 'Agent Instructions';

    protected static ?string $title = 'Agent Instructions';

    protected string $view = 'ai-agent::filament.pages.manage-agent-instructions';

    /**
     * @var array<string, mixed>|null
     */
    public ?array $active = null;

    public ?string $activeError = null;

    public static function canAccess(): bool
    {
        return auth()->user()?->can('manage_ai_agent') ?? false;
    }

    public function mount(): void
    {
        $this->refreshActive();
    }

    public function table(Table $table): Table
    {
        return $table
            ->records(function (int $page, int $recordsPerPage): LengthAwarePaginator {
                $result = app(BnfexpressAdminClient::class)->listInstructions(
                    limit: $recordsPerPage,
                    offset: ($page - 1) * $recordsPerPage,
                );

                $items = $result['instructions'] ?? (array_is_list($result) ? $result : []);
                $total = $result['total'] ?? (($page - 1) * $recordsPerPage) + count($items) + (count($items) === $recordsPerPage ? 1 : 0);

                return new LengthAwarePaginator(
                    items: collect($items)->mapWithKeys(fn (array $item): array => [$item['id'] => $item]),
                    total: $total,
                    perPage: $recordsPerPage,
                    currentPage: $page,
                );
            })
            ->columns([
                TextColumn::make('id'),
                IconColumn::make('is_active')->boolean(),
                TextColumn::make('content')->limit(80)->wrap(),
                TextColumn::make('created_at')->dateTime(),
            ])
            ->recordActions([
                Action::make('activate')
                    ->label('Activate')
                    ->icon(Heroicon::OutlinedArrowUturnLeft)
                    ->visible(fn (array $record): bool => ! ($record['is_active'] ?? false))
                    ->requiresConfirmation()
                    ->action(function (array $record): void {
                        $this->callBnfexpress(
                            fn () => app(BnfexpressAdminClient::class)->activateInstruction($record['id']),
                            successTitle: 'Instruction activated',
                            failureTitle: 'Failed to activate instruction',
                        );

                        $this->resetTable();
                        $this->refreshActive();
                    }),
            ])
            ->headerActions([
                Action::make('publish')
                    ->label('Publish New Version')
                    ->icon(Heroicon::OutlinedPlusCircle)
                    ->schema([
                        Textarea::make('content')
                            ->required()
                            ->rows(10),
                        Toggle::make('activate')
                            ->label('Activate immediately')
                            ->default(true)
                            ->helperText('Deactivates the current active version automatically.'),
                    ])
                    ->action(function (array $data): void {
                        $this->callBnfexpress(
                            fn () => app(BnfexpressAdminClient::class)->publishInstruction($data['content'], $data['activate']),
                            successTitle: 'New instruction version published',
                            failureTitle: 'Failed to publish instruction',
                        );

                        $this->resetTable();
                        $this->refreshActive();
                    }),
            ]);
    }

    private function refreshActive(): void
    {
        try {
            $this->active = app(BnfexpressAdminClient::class)->getActiveInstruction();
            $this->activeError = null;
        } catch (BnfexpressApiException $exception) {
            $this->active = null;
            $this->activeError = $exception->getMessage();

            Notification::make()
                ->title('Could not load the active instruction')
                ->body($exception->getMessage())
                ->danger()
                ->send();
        }
    }
}
