<?php

namespace App\Filament\Resources\Styles;

use App\Models\Style;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Actions\BulkAction;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Components\Tabs\Tab;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Spatie\SimpleExcel\SimpleExcelReader;

class StyleResource extends Resource
{
    protected static ?string $model = Style::class;

    protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-rectangle-stack';

    protected static ?int $navigationSort = -80;

    public static function getNavigationGroup(): ?string
    {
        return __('filament.navigation.groups.ai_models');
    }

    public static function getNavigationLabel(): string
    {
        return __('filament.navigation.styles');
    }

    public static function form(Schema $schema): Schema
    {
        return $schema
            ->columns(1)
            ->components([
                Tabs::make('Style Details')
                    ->tabs([
                        Tab::make('General')
                            ->components([
                                Grid::make(2)
                                    ->columnSpanFull()
                                    ->components([
                                        TextInput::make('title')
                                            ->required()
                                            ->maxLength(255),
                                        Toggle::make('enabled')
                                            ->default(true),
                                    ]),
                                Grid::make(2)
                                    ->columnSpanFull()
                                    ->components([
                                        Textarea::make('prompt')
                                            ->required()
                                            ->rows(5),
                                        Textarea::make('description')
                                            ->required()
                                            ->rows(5),
                                        FileUpload::make('preview_source')
                                            ->label('Referenzbild für Vorschau')
                                            ->helperText('Lade ein Bild hoch, um eine Vorschau mit dem aktuellen Prompt zu generieren.')
                                            ->disk('public')
                                            ->directory('style_previews/reference')
                                            ->image()
                                            ->dehydrated(false),
                                    ]),
                                Select::make('ai_model_id')
                                    ->relationship('aiModel', 'name')
                                    ->label(__('filament.resource.style.form.ai_model'))
                                    ->required(),
                                FileUpload::make('preview_image')
                                    ->disk('public')
                                    ->directory('style_previews')
                                    ->image()
                                    ->imageEditor()
                                    ->required(),
                            ]),
                        Tab::make('Details')
                            ->components([
                                TextInput::make('sort_order')
                                    ->label(__('filament.resource.style.form.sort_order'))
                                    ->numeric()
                                    ->default(0),
                                Textarea::make('parameters')
                                    ->label(__('filament.resource.style.form.parameters'))
                                    ->nullable()
                                    ->rows(15),
                            ]),
                    ]),
            ]);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->defaultSort('sort_order')
            ->columns([
                TextColumn::make('title')->label(__('filament.resource.style.table.title'))->searchable()->sortable(),
                IconColumn::make('enabled')
                    ->label(__('filament.resource.style.table.enabled'))
                    ->boolean(),
                TextColumn::make('aiModel.name')->label(__('filament.resource.style.table.ai_model'))->searchable()->sortable(),
                ImageColumn::make('preview_image')->label(__('filament.resource.style.table.preview_image'))->disk('public'),
                TextColumn::make('sort_order')->label(__('filament.resource.style.table.sort_order'))->sortable(),
            ])
            ->filters([
                SelectFilter::make('ai_model')
                    ->relationship('aiModel', 'name'),
            ])
            ->deferFilters(false)
            ->headerActions([
                Action::make('import_styles')
                    ->label(__('filament.resource.style.import.title'))
                    ->icon('heroicon-o-arrow-up-on-square-stack')
                    ->form([
                        FileUpload::make('import_file')
                            ->label(__('filament.resource.style.import.file_label'))
                            ->acceptedFileTypes([
                                'text/csv',
                                'text/plain',
                                'application/vnd.ms-excel',
                                'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                            ])
                            ->directory('imports/styles')
                            ->visibility('private')
                            ->required(),
                        Select::make('ai_model_id')
                            ->label(__('filament.resource.style.import.model_label'))
                            ->relationship('aiModel', 'name')
                            ->required(),
                    ])
                    ->action(function (array $data): void {
                        $path = storage_path('app/'.$data['import_file']);

                        if (! file_exists($path)) {
                            throw new \RuntimeException('Import-Datei nicht gefunden.');
                        }

                        $rows = self::parseImportFile($path);

                        if (empty($rows)) {
                            throw new \RuntimeException(__('filament.resource.style.import.empty'));
                        }

                        $created = 0;
                        foreach ($rows as $row) {
                            $title = $row['title'] ?? null;
                            $prompt = $row['prompt'] ?? null;
                            $description = $row['description'] ?? null;

                            if (! $title || ! $prompt) {
                                continue;
                            }

                            Style::create([
                                'title' => $title,
                                'prompt' => $prompt,
                                'description' => $description ?? '',
                                'preview_image' => '', // user must set later
                                'ai_model_id' => $data['ai_model_id'],
                                'enabled' => true,
                                'sort_order' => 0,
                            ]);
                            $created++;
                        }

                        if ($created === 0) {
                            throw new \RuntimeException('Es wurden keine Styles importiert.');
                        }

                        \Filament\Notifications\Notification::make()
                            ->title(__('filament.resource.style.import.title'))
                            ->body($created.' '.__('filament.resource.style.import.success'))
                            ->success()
                            ->send();
                    }),
            ])
            ->actions([
                EditAction::make(),
                Action::make('duplicate')
                    ->label(__('filament.resource.style.action.duplicate'))
                    ->icon('heroicon-o-document-duplicate')
                    ->action(function (\App\Models\Style $record) {
                        $newStyle = $record->replicate();
                        $newStyle->title = $record->title.' (Kopie)';
                        $newStyle->save();

                        return redirect()->to(\App\Filament\Resources\Styles\StyleResource::getUrl('edit', ['record' => $newStyle->id]));
                    }),
            ])
            ->bulkActions([
                BulkActionGroup::make([
                    DeleteBulkAction::make(),
                    BulkAction::make('enable')
                        ->label(__('filament.resource.style.action.enable_selected'))
                        ->icon('heroicon-o-check-circle')
                        ->action(function (\Illuminate\Support\Collection $records) {
                            $records->each->update(['enabled' => true]);
                        }),
                    BulkAction::make('disable')
                        ->label(__('filament.resource.style.action.disable_selected'))
                        ->icon('heroicon-o-x-circle')
                        ->action(function (\Illuminate\Support\Collection $records) {
                            $records->each->update(['enabled' => false]);
                        }),
                    BulkAction::make('reassignModel')
                        ->label(__('filament.resource.style.action.reassign_model'))
                        ->icon('heroicon-o-arrow-path')
                        ->form([
                            Select::make('ai_model_id')
                                ->label('Zielmodell')
                                ->relationship('aiModel', 'name')
                                ->required(),
                        ])
                        ->action(function (\Illuminate\Support\Collection $records, array $data) {
                            $count = 0;
                            foreach ($records as $record) {
                                $record->update(['ai_model_id' => $data['ai_model_id']]);
                                $count++;
                            }

                            \Filament\Notifications\Notification::make()
                                ->title(__('filament.resource.style.action.reassign_model'))
                                ->body("{$count} ".__('filament.resource.style.table.title'))
                                ->success()
                                ->send();
                        }),
                    BulkAction::make('duplicateToModel')
                        ->label(__('filament.resource.style.action.duplicate_to_model'))
                        ->icon('heroicon-o-document-duplicate')
                        ->form([
                            Select::make('ai_model_id')
                                ->label('Zielmodell')
                                ->relationship('aiModel', 'name')
                                ->required(),
                        ])
                        ->action(function (\Illuminate\Support\Collection $records, array $data) {
                            $created = 0;
                            foreach ($records as $record) {
                                $copy = $record->replicate();
                                $copy->title = $record->title.' (Copy)';
                                $copy->ai_model_id = $data['ai_model_id'];
                                $copy->save();
                                $created++;
                            }

                            \Filament\Notifications\Notification::make()
                                ->title(__('filament.resource.style.action.duplicate'))
                                ->body("{$created} Kopien erstellt.")
                                ->success()
                                ->send();
                        }),
                ]),
            ])
            ->emptyStateActions([
                CreateAction::make(),
            ]);
    }

    public static function getRelations(): array
    {
        return [
            //
        ];
    }

    protected static function parseImportFile(string $path): array
    {
        return SimpleExcelReader::create($path)->getRows()->map(function (array $row) {
            $normalized = [];
            foreach ($row as $key => $value) {
                $normalized[strtolower(trim($key))] = is_string($value) ? trim($value) : $value;
            }

            return [
                'title' => $normalized['title'] ?? $normalized['titel'] ?? null,
                'prompt' => $normalized['prompt'] ?? null,
                'description' => $normalized['description'] ?? $normalized['beschreibung'] ?? null,
            ];
        })->filter(function (array $row) {
            return ! empty($row['title']) && ! empty($row['prompt']);
        })->values()->all();
    }

    public static function getPages(): array
    {
        return [
            'index' => Pages\ListStyles::route('/'),
            'create' => Pages\CreateStyle::route('/create'),
            'edit' => Pages\EditStyle::route('/{record}/edit'),
        ];
    }
}
