<?php

namespace App\Filament\Resources\Entries\Schemas;

use App\Models\Category;
use Filament\Actions\Action;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
use Filament\Forms\Components\SpatieTagsInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Schemas\Schema;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Spatie\MediaLibrary\MediaCollections\Models\Media;

class EntryForm
{
    public static function configure(Schema $schema): Schema
    {
        return $schema
            ->components([
                Select::make('type')
                    ->options([
                        'article' => 'Article',
                        'card' => 'Card',
                        'text' => 'Text',
                        'image' => 'Image',
                    ])
                    ->default('article')
                    ->required()
                    ->live(),
                TextInput::make('title')
                    ->required()
                    ->live(onBlur: true)
                    ->afterStateUpdated(function ($state, $set): void {
                        $set('slug', Str::slug((string) $state));
                    }),
                TextInput::make('slug')
                    ->required()
                    ->visible(fn($get) => $get('type') === 'article')
                    ->dehydrated()
                    ->readOnly(),
                Textarea::make('description')
                    ->visible(fn($get) => $get('type') === 'article')
                    ->columnSpanFull(),
                SpatieTagsInput::make('tags')
                    ->type('entry-tags')
                    ->visible(fn($get) => $get('type') === 'article')
                    ->columnSpanFull(),
                SpatieMediaLibraryFileUpload::make('featured_image')
                    ->visible(
                        fn($get) =>
                        $get('type') === 'article' || $get('type') === 'image'
                    )
                    ->collection('featured-image')
                    ->image()
                    ->imageEditor()
                    ->disk(config('media-library.disk_name', 'public'))
                    ->visibility('public')
                    ->columnSpanFull()
                    ->dehydrated(false)
                    ->saveUploadedFileUsing(function ($file, $record) {
                        $diskName = config('media-library.disk_name', 'public');

                        if (config('app.env') === 'local') {
                            Log::info('Featured Image Upload Debug', [
                                'disk' => $diskName,
                                'file_name' => $file->getClientOriginalName(),
                                'file_size' => $file->getSize(),
                                'file_mime' => $file->getMimeType(),
                                'file_path' => $file->getRealPath(),
                                'record_id' => $record?->id,
                                'aws_config' => [
                                    'bucket' => config('filesystems.disks.s3.bucket'),
                                    'region' => config('filesystems.disks.s3.region'),
                                    'key_exists' => !empty(config('filesystems.disks.s3.key')),
                                    'secret_exists' => !empty(config('filesystems.disks.s3.secret')),
                                ]
                            ]);
                        }

                        try {
                            if (!$record) {
                                throw new \Exception('Record not found during upload');
                            }

                            // Test S3 connection if using S3
                            if ($diskName === 's3') {
                                $disk = \Storage::disk('s3');

                                // Test basic S3 connectivity
                                $testFile = 'test-' . time() . '.txt';
                                $disk->put($testFile, 'test content');
                                $disk->delete($testFile);

                                if (config('app.env') === 'local') {
                                    Log::info('S3 connectivity test passed');
                                }
                            }

                            // Use addMedia with the file directly, not addMediaFromRequest
                            // Generate secure filename similar to Livewire temp files
                            $originalName = $file->getClientOriginalName();
                            $extension = pathinfo($originalName, PATHINFO_EXTENSION);
                            $baseName = pathinfo($originalName, PATHINFO_FILENAME);

                            // Generate secure filename with encoded original name
                            $encodedName = base64_encode($originalName);
                            $secureFileName = Str::random(32) . '-meta' . $encodedName . '-.' . $extension;

                            $media = $record->addMedia($file->getRealPath())
                                ->usingName($baseName) // Keep original name for display/search
                                ->usingFileName($secureFileName) // Use secure filename for storage
                                ->toMediaCollection('featured-image', $diskName);

                            if (config('app.env') === 'local') {
                                Log::info('Featured Image Upload Success', [
                                    'media_id' => $media->id,
                                    'media_url' => $media->getUrl(),
                                    'media_path' => $media->getPathRelativeToRoot(),
                                    'disk' => $media->disk
                                ]);
                            }

                            return $media->getUrl();
                        } catch (\Exception $e) {
                            Log::error('Featured Image Upload Failed', [
                                'error' => $e->getMessage(),
                                'trace' => $e->getTraceAsString(),
                                'disk' => $diskName,
                                'file_name' => $file->getClientOriginalName()
                            ]);


                            // Also show error to user
                            \Filament\Notifications\Notification::make()
                                ->danger()
                                ->title('Upload Failed')
                                ->body($e->getMessage())
                                ->persistent()
                                ->send();

                            throw $e;
                        }
                    })
                    ->hintAction(
                        Action::make('featured_picker')
                            ->label('Featured Image from Gallery')
                            ->icon('heroicon-m-photo')
                            ->extraAttributes(['id' => 'featured-picker-button'])
                            ->schema([
                                Select::make('image_id')
                                    ->label('Select an existing image')
                                    ->allowHtml()
                                    ->options(function () {
                                        $currentDisk = config('media-library.disk_name', 'public');
                                        return Media::where('disk', $currentDisk)
                                            ->latest()
                                            ->limit(50)
                                            ->get(['id', 'file_name', 'name', 'disk'])
                                            ->mapWithKeys(function (Media $item) {
                                                try {
                                                    $url = $item->getUrl();
                                                    $fileName = e($item->file_name);
                                                    $name = e($item->name ?? '');

                                                    $html = "<div class='flex items-center gap-3'>" .
                                                        "<img src='{$url}' class='rounded' style='width:60px;height:60px;object-fit:cover;' alt='{$fileName}' loading='lazy' />" .
                                                        "<div class='flex flex-col'>" .
                                                        "<span class='font-medium text-sm'>{$name}</span>" .
                                                        "<span class='text-xs text-gray-500'>{$fileName}</span>" .
                                                        '</div></div>';

                                                    return [$item->id => $html];
                                                } catch (\Exception $e) {
                                                    return [];
                                                }
                                            })->toArray();
                                    })
                                    ->searchable()
                                    ->preload()
                                    ->required(),
                            ])
                            ->action(function (array $data, SpatieMediaLibraryFileUpload $component): void {
                                $record = $component->getRecord();
                                $diskName = config('media-library.disk_name', 'public');

                                if (config('app.env') === 'local') {
                                    Log::info('Featured Image Picker Action Debug', [
                                        'disk' => $diskName,
                                        'record_id' => $record?->id,
                                        'image_id' => $data['image_id'] ?? null
                                    ]);
                                }

                                if (! $record) {
                                    \Filament\Notifications\Notification::make()
                                        ->warning()
                                        ->title('Save the entry first')
                                        ->send();

                                    return;
                                }

                                if (! $data['image_id']) {
                                    return;
                                }

                                $sourceMedia = Media::find($data['image_id']);
                                if (! $sourceMedia) {
                                    Log::error('Source media not found', ['image_id' => $data['image_id']]);
                                    \Filament\Notifications\Notification::make()
                                        ->danger()
                                        ->title('Source image not found in database')
                                        ->send();
                                    return;
                                }

                                try {
                                    // For S3, we need to handle file copying differently
                                    if ($sourceMedia->disk === 's3') {
                                        if (config('app.env') === 'local') {
                                            Log::info('Copying S3 media to new collection', [
                                                'source_disk' => $sourceMedia->disk,
                                                'source_path' => $sourceMedia->getPathRelativeToRoot(),
                                                'target_disk' => $diskName
                                            ]);
                                        }

                                        // Copy from S3 to S3 or download temporarily
                                        $sourceDisk = \Storage::disk($sourceMedia->disk);
                                        $sourceContent = $sourceDisk->get($sourceMedia->getPathRelativeToRoot());

                                        if (!$sourceContent) {
                                            throw new \Exception('Could not read source file from S3');
                                        }

                                        $tempCopy = sys_get_temp_dir() . '/' . uniqid() . '_' . $sourceMedia->file_name;
                                        file_put_contents($tempCopy, $sourceContent);
                                    } else {
                                        // Local file handling
                                        $sourceFile = $sourceMedia->getPath();
                                        if (! file_exists($sourceFile)) {
                                            throw new \Exception('Source file not found on disk');
                                        }

                                        $tempCopy = sys_get_temp_dir() . '/' . uniqid() . '_' . $sourceMedia->file_name;
                                        copy($sourceFile, $tempCopy);
                                    }

                                    // Verify record has ID
                                    if (! $record->id) {
                                        \Filament\Notifications\Notification::make()
                                            ->danger()
                                            ->title('Entry must be saved first')
                                            ->send();
                                        return;
                                    }

                                    // Add the copy to the entry's featured-image collection
                                    $newMedia = $record->addMedia($tempCopy)
                                        ->usingName($sourceMedia->name ?: pathinfo($sourceMedia->file_name, PATHINFO_FILENAME))
                                        ->usingFileName($sourceMedia->file_name)
                                        ->toMediaCollection('featured-image', $diskName);

                                    if (config('app.env') === 'local') {
                                        Log::info('Featured Image Picker Success', [
                                            'new_media_id' => $newMedia->id,
                                            'new_media_disk' => $newMedia->disk,
                                            'new_media_url' => $newMedia->getUrl()
                                        ]);
                                    }

                                    // Dispatch event for app.js to handle
                                    $component->getLivewire()->dispatch('featured-image-added', ['mediaId' => $newMedia->id]);

                                    \Filament\Notifications\Notification::make()
                                        ->success()
                                        ->title('Image added to featured image')
                                        ->send();
                                } catch (\Exception $e) {
                                    Log::error('Featured Image Picker Failed', [
                                        'error' => $e->getMessage(),
                                        'trace' => $e->getTraceAsString(),
                                        'source_media_id' => $data['image_id'],
                                        'disk' => $diskName
                                    ]);

                                    \Filament\Notifications\Notification::make()
                                        ->danger()
                                        ->title('Error: ' . $e->getMessage())
                                        ->persistent()
                                        ->send();
                                } finally {
                                    if (isset($tempCopy) && file_exists($tempCopy)) {
                                        unlink($tempCopy);
                                    }
                                }
                            })
                    ),
                Toggle::make('is_published')
                    ->required(),
                Toggle::make('is_featured')
                    ->required(),
                TextInput::make('priority')
                    ->label('Priority')
                    ->numeric()
                    ->default(0)
                    ->required(),
                DatePicker::make('published_at')
                    ->visible(fn($get) => $get('type') === 'article'),
                Select::make('category_id')
                    ->label('Category')
                    ->options(function () {
                        return Category::all()
                            ->pluck('name', 'id')
                            ->toArray();
                    })
                    ->searchable(),
                TextInput::make('call_to_action_text')
                    ->label('Call to Action Text')
                    ->visible(fn($get) => $get('type') !== 'article'),
                TextInput::make('call_to_action_link')
                    ->label('Call to Action URL')
                    ->visible(fn($get) => $get('type') !== 'article'),

                RichEditor::make('content')
                    ->visible(fn($get) => $get('type') !== 'image')
                    ->columnSpanFull()
                    ->hintAction(
                        Action::make('picker')
                            ->label('Gallery Picker')
                            ->icon('heroicon-m-photo')
                            ->schema([
                                Select::make('image_url')
                                    ->label('Select an existing image')
                                    ->allowHtml()
                                    ->options(function () {
                                        return Media::latest()
                                            ->limit(30) // Limit to 30 most recent items for performance
                                            ->get(['id', 'file_name', 'name', 'uuid', 'collection_name', 'model_type', 'model_id', 'disk'])
                                            ->filter(function (Media $item) {
                                                // Only include media items that have a valid disk
                                                return $item->disk !== null;
                                            })
                                            ->mapWithKeys(function (Media $item) {
                                                try {
                                                    $url = $item->getUrl();
                                                } catch (\Exception $e) {
                                                    // Skip items that can't generate URLs
                                                    return [];
                                                }

                                                $fileName = e($item->file_name);
                                                $name = e($item->name ?? '');

                                                // Smaller image preview for better performance
                                                $html = "<div class='flex items-center gap-3'>" .
                                                    "<img src='{$url}' class='rounded' style='width:60px;height:60px;object-fit:cover;' alt='{$fileName}' loading='lazy' />" .
                                                    "<div class='flex flex-col'>" .
                                                    "<span class='font-medium text-sm'>{$name}</span>" .
                                                    "<span class='text-xs text-gray-500'>{$fileName}</span>" .
                                                    '</div></div>';

                                                return [$url => $html];
                                            })->toArray();
                                    })
                                    ->searchable()
                                    ->preload()
                                    ->required(),
                            ])
                            ->action(function (array $data, RichEditor $component) {
                                // We dispatch the URL to the browser to be inserted into TipTap
                                $component->getLivewire()->dispatch('insert-editor-content', [
                                    'statePath' => $component->getStatePath(),
                                    'html' => "<img src='{$data['image_url']}' alt=''>",
                                ]);
                            })
                    ),

            ]);
    }
}
