<?php

namespace App\Filament\Resources\Manage\DataChanges;

use App\Enums\DataChangeStatus;
use App\Enums\RoleEnum;
use App\Filament\Actions\DefaultBulkActions;
use App\Filament\Resources\Manage\DataChanges\Actions\DataChangeRequest\AcceptAction;
use App\Filament\Resources\Manage\DataChanges\Actions\DataChangeRequest\RejectAction;
use App\Filament\Resources\Manage\DataChanges\Pages\ManageDataChanges;
use App\Filament\Resources\Manage\DataChanges\Pages\ViewDataChange;
use App\Models\Company;
use App\Models\DataChangeRequest;
use App\Models\Journalist;
use App\Models\PartnerMedia;
use BackedEnum;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\ViewAction;
use Filament\Infolists\Components\TextEntry;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\TrashedFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Storage;
use UnitEnum;

class DataChangesResource extends Resource
{
    protected static ?string $model = DataChangeRequest::class;

    protected static string|UnitEnum|null $navigationGroup = 'Kelola';

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

    protected static ?string $navigationLabel = 'Permohonan Perubahan Data';

    protected static ?int $navigationSort = 8;

    protected static ?string $recordTitleAttribute = 'change_reason';

    protected static ?string $slug = 'manage/data-changes';

    public static function getNavigationBadge(): ?string
    {
        if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN)) {
            return null;
        }

        return static::getModel()::pending()->count();
    }

    public static function infolist(Schema $schema): Schema
    {
        return $schema
            ->schema([
                Section::make('Perbandingan Data')
                    ->schema([
                        TextEntry::make('comparison')
                            ->hiddenLabel()
                            ->html()
                            ->state(function (DataChangeRequest $record): string {
                                $old = $record->old_data ?? [];
                                $new = $record->new_data ?? [];

                                if (! is_array($old) || ! is_array($new)) {
                                    return '<em>Format data tidak valid.</em>';
                                }

                                $renderValue = function ($value) {
                                    if (empty($value)) {
                                        return '<em>Kosong</em>';
                                    }

                                    $paths = is_array($value) ? $value : [$value];
                                    $isProbablyPath = false;

                                    foreach ($paths as $path) {
                                        if (is_string($path) && (str_contains($path, '/') || str_contains($path, '\\'))) {
                                            $isProbablyPath = true;
                                            break;
                                        }
                                    }

                                    if ($isProbablyPath) {
                                        return collect($paths)
                                            ->map(function ($path) {
                                                if (! is_string($path)) {
                                                    return e(json_encode($path));
                                                }

                                                $url = Storage::disk(config('filesystems.default'))->url($path);
                                                $extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));

                                                if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'])) {
                                                    return "<a href='{$url}' target='_blank'><img src='{$url}' style='max-height:100px; border-radius:8px; margin-top:4px; border:1px solid #e5e7eb;'></a>";
                                                }

                                                if ($extension === 'pdf') {
                                                    return "
                                                        <div style='margin-top:4px;'>
                                                            <iframe src='{$url}' style='width:100%; height:300px; border:1px solid #e5e7eb; border-radius:8px;'></iframe>
                                                            <a href='{$url}' target='_blank' style='display:block; margin-top:4px; color:#3b82f6; text-decoration:underline; font-size:0.75rem;'>↗️ Buka PDF di Tab Baru</a>
                                                        </div>
                                                    ";
                                                }

                                                return "<a href='{$url}' target='_blank' style='color:#3b82f6; text-decoration:underline; font-size:0.875rem;'>📎 Buka Dokumen (".strtoupper($extension).')</a>';
                                            })
                                            ->implode('<br>');
                                    }

                                    return e(is_scalar($value) ? $value : json_encode($value));
                                };

                                // 1. Deletion Request
                                if (isset($new['__delete_request__']) && $new['__delete_request__'] === true) {
                                    return "
                                        <div style='background-color:#fee2e2; border:1px solid #f87171; color:#991b1b; padding:16px; border-radius:8px; margin-bottom:16px;'>
                                            <div style='font-weight:700; font-size:1.125rem; margin-bottom:4px;'>🚮 Permohonan Penghapusan Data</div>
                                            <p style='font-size:0.875rem;'>User mengajukan penghapusan permanen untuk data ini. Semua informasi terkait akan dihapus setelah disetujui.</p>
                                        </div>
                                    ";
                                }

                                // 2. New Addition Request
                                if (empty($old)) {
                                    $rows = collect($new)
                                        ->map(function ($value, $key) use ($renderValue) {
                                            return sprintf(
                                                "<div style='margin-bottom:12px; border-bottom:1px solid #f3f4f6; padding-bottom:8px'>
                                                    <div style='font-weight:600; color:#374151; margin-bottom:4px'>%s</div>
                                                    <div style='color:#16a34a; font-weight:500;'>[BARU]</div>
                                                    <div style='margin-top:4px'>%s</div>
                                                </div>",
                                                e($key),
                                                $renderValue($value)
                                            );
                                        })
                                        ->implode('');

                                    return "
                                        <div style='background-color:#f0fdf4; border:1px solid #bbf7d0; color:#166534; padding:16px; border-radius:8px; margin-bottom:16px;'>
                                            <div style='font-weight:700; font-size:1.125rem; margin-bottom:4px;'>✨ Permohonan Penambahan Data</div>
                                            <p style='font-size:0.875rem;'>Berikut adalah data baru yang akan dibuat.</p>
                                        </div>
                                        {$rows}
                                    ";
                                }

                                // 3. Standard Comparison (Update)
                                return collect($new)
                                    ->map(function ($newValue, $key) use ($old, $renderValue) {
                                        $oldValue = $old[$key] ?? null;

                                        if ($oldValue === $newValue) {
                                            return null;
                                        }

                                        return sprintf(
                                            "<div style='margin-bottom:16px; border-bottom:1px solid #f3f4f6; padding-bottom:12px'>
                                                <div style='font-weight:600; color:#374151; margin-bottom:4px'>%s</div>
                                                <div style='display:grid; grid-template-columns: 1fr 1fr; gap:16px'>
                                                    <div>
                                                        <span style='font-size:0.75rem; font-weight:700; color:#dc2626; text-transform:uppercase'>LAMA</span>
                                                        <div style='margin-top:2px'>%s</div>
                                                    </div>
                                                    <div>
                                                        <span style='font-size:0.75rem; font-weight:700; color:#16a34a; text-transform:uppercase'>BARU</span>
                                                        <div style='margin-top:2px'>%s</div>
                                                    </div>
                                                </div>
                                            </div>",
                                            e($key),
                                            $renderValue($oldValue),
                                            $renderValue($newValue)
                                        );
                                    })
                                    ->filter()
                                    ->implode('');
                            })
                            ->columnSpanFull(),
                    ]),
            ])
            ->columns(1);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('user.name')
                    ->label('Pemohon')
                    ->searchable()
                    ->sortable()
                    ->description(fn (DataChangeRequest $record): ?string => $record?->entity?->name)
                    ->visible(! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)),

                TextColumn::make('entity_type')
                    ->label('Jenis Data')
                    ->searchable()
                    ->sortable()
                    ->description(fn (DataChangeRequest $record): ?string => match (true) {
                        isset($record->new_data['__delete_request__']) => '🗑️ Penghapusan',
                        empty($record->old_data) => '✨ Penambahan',
                        default => '📝 Perubahan',
                    })
                    ->formatStateUsing(fn (DataChangeRequest $record): ?string => match ($record->entity_type) {
                        Company::class => 'Perusahaan',
                        PartnerMedia::class => 'Media',
                        Journalist::class => 'Jurnalis',
                        default => 'Lainnya',
                    })
                    ->color(fn (DataChangeRequest $record): ?string => match ($record->entity_type) {
                        Company::class => 'success',
                        PartnerMedia::class => 'info',
                        Journalist::class => 'warning',
                        default => 'secondary',
                    })
                    ->badge(),

                TextColumn::make('status')
                    ->label('Status')
                    ->searchable()
                    ->sortable()
                    ->badge()
                    ->formatStateUsing(fn (DataChangeStatus $state): string => $state->getLabel())
                    ->color(fn (DataChangeStatus $state): string => $state->getColor())
                    ->description(fn (DataChangeRequest $record): ?string => $record?->review ? 'Oleh: '.$record->review?->reviewer?->name : ''),

                TextColumn::make('change_reason')
                    ->label('Alasan Perubahan')
                    ->limit(50),

                TextColumn::make('review.note')
                    ->label('Alasan Penolakan')
                    ->limit(50),

                TextColumn::make('created_at')
                    ->label('Tgl Permohonan')
                    ->date()
                    ->sortable()
                    ->dateTime('l, d F Y H:i:s')
                    ->wrap(),
            ])
            ->filters([
                TrashedFilter::make()
                    ->native(false)
                    ->visible(fn () => auth()->user()?->hasRole(RoleEnum::DEVELOPER->value)),
            ])
            ->recordActions([
                ViewAction::make(),
                AcceptAction::make('accept'),
                RejectAction::make('reject'),
            ])
            ->toolbarActions([
                BulkActionGroup::make([
                    ...DefaultBulkActions::make('permohonan perubahan data'),
                ]),
            ])
            ->emptyStateIcon(Heroicon::DocumentText)
            ->emptyStateDescription('Belum ada permohonan perubahan data.')
            ->defaultSort('created_at', 'desc')
            ->deferFilters(false)
            ->modifyQueryUsing(function (Builder $query): void {
                $query->when(auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value), function (Builder $q): Builder {
                    return $q->where('user_id', auth()->id());
                });
            });
    }

    public static function getPages(): array
    {
        return [
            'index' => ManageDataChanges::route('/'),
            'view' => ViewDataChange::route('/{record}'),
        ];
    }
}
