<?php

namespace App\Filament\Resources\PricelistFiles\RelationManagers;

use App\Enums\PricelistFileLineStatusEnum;
use App\Enums\PricelistFileStatusEnum;
use App\Services\PriceListService;
use Filament\Actions\ViewAction;
use Filament\Infolists\Components\TextEntry;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Components\EmbeddedTable;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\RenderHook;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Text;
use Filament\Schemas\Schema;
use Filament\Support\Facades\FilamentView;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Tables\View\TablesRenderHook;
use Filament\View\PanelsRenderHook;
use Filament\Support\Enums\Width;
use Illuminate\Support\HtmlString;
use Filament\Schemas\Components\Tabs\Tab;
use Illuminate\Database\Eloquent\Builder;

class LinesRelationManager extends RelationManager
{
    protected static string $relationship = 'lines';

    protected static ?string $title = 'Feldolgozott sorok';

    public function booted()
    {
        FilamentView::registerRenderHook(
            TablesRenderHook::TOOLBAR_START,
            fn () => $this->getTabsContentComponent()->container($this->makeSchema())->toHtml(),
            scopes: static::class,
        );
    }

    public function content(Schema $schema): Schema
    {
        return $schema
            ->components([
                RenderHook::make(PanelsRenderHook::RESOURCE_RELATION_MANAGER_BEFORE),
                EmbeddedTable::make(),
                RenderHook::make(PanelsRenderHook::RESOURCE_RELATION_MANAGER_AFTER),
            ]);
    }

    public function getTabs(): array
    {
        $ownerRecord = $this->getOwnerRecord();
        $counts = $ownerRecord->lines()
            ->selectRaw('status, count(*) as count')
            ->groupBy('status')
            ->pluck('count', 'status');

        return [
            'all' => Tab::make('Mind')
                ->badge($counts->sum()),
            'hibas' => Tab::make('Hibás')
                ->icon(PricelistFileLineStatusEnum::error->icon())
                ->badgeColor(PricelistFileLineStatusEnum::error->color())
                ->badge($counts->get(PricelistFileLineStatusEnum::error->value, 0))
                ->modifyQueryUsing(fn (Builder $query) => $query->where('status', PricelistFileLineStatusEnum::error)),
            'warning' => Tab::make('Figyelmeztetések')
                ->icon(PricelistFileLineStatusEnum::warning->icon())
                ->badgeColor(PricelistFileLineStatusEnum::warning->color())
                ->badge($counts->get(PricelistFileLineStatusEnum::warning->value, 0))
                ->modifyQueryUsing(fn (Builder $query) => $query->where('status', PricelistFileLineStatusEnum::warning)),
            'uj' => Tab::make('Új')
                ->icon(PricelistFileLineStatusEnum::new_product->icon())
                ->badgeColor(PricelistFileLineStatusEnum::new_product->color())
                ->badge($counts->get(PricelistFileLineStatusEnum::new_product->value, 0))
                ->modifyQueryUsing(fn (Builder $query) => $query->where('status', PricelistFileLineStatusEnum::new_product)),
            'modosult' => Tab::make('Módosult')
                ->icon(PricelistFileLineStatusEnum::updated->icon())
                ->badgeColor(PricelistFileLineStatusEnum::updated->color())
                ->badge($counts->get(PricelistFileLineStatusEnum::updated->value, 0))
                ->modifyQueryUsing(fn (Builder $query) => $query->where('status', PricelistFileLineStatusEnum::updated)),
        ];
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                Grid::make(1)
                    ->schema([
                        Section::make('Módosulások')
                            ->schema([
                                Text::make(fn ($record) => new HtmlString(
                                    '<div class="grid grid-cols-1 gap-4">' .
                                    collect($record->diff ?? [])->map(function ($d, $field) {
                                        $old = $d['old_label'] ?? $d['old'] ?? 'N/A';
                                        $new = $d['new_label'] ?? $d['new'] ?? 'N/A';
                                        $label = $d['label'] ?? $field;

                                        if ($old === '' || $old === null) $old = '<i>(üres)</i>';
                                        if ($new === '' || $new === null) $new = '<i>(üres)</i>';

                                        // Ár formázása ha árról van szó
                                        if ($field === 'price') {
                                            $old = number_format((float)($d['old'] ?? 0), 2, ',', ' ') . ' Ft';
                                            $new = number_format((float)($d['new'] ?? 0), 2, ',', ' ') . ' Ft';
                                        }

                                        return "<div class='text-sm border-l-4 border-info-500 pl-3 py-1 bg-info-50/50 dark:bg-info-950/20'>
                                                    <div class='font-bold text-gray-700 dark:text-gray-300'>$label</div>
                                                    <div class='flex items-center gap-2 mt-1'>
                                                        <span class='text-gray-500 line-through'>$old</span>
                                                        <span class='text-gray-400'>→</span>
                                                        <span class='text-info-600 font-bold'>$new</span>
                                                    </div>
                                                </div>";
                                    })->join('') .
                                    '</div>'
                                )),
                            ])
                            ->visible(fn ($record) => !empty($record->diff)),

                        Section::make('Validációs üzenetek')
                            ->schema([
                                Text::make(fn ($record) => new HtmlString(
                                    '<ul class="list-disc ml-5">' .
                                    collect($record->validation_messages ?? [])->map(fn ($msg) => "<li>$msg</li>")->join('') .
                                    '</ul>'
                                )),
                            ])
                            ->visible(fn ($record) => !empty($record->validation_messages)),
                    ])
                    ->columnSpan(1)
                    ->visible(fn ($record) => !empty($record->diff) || !empty($record->validation_messages)),

                Section::make('Adatok')
                    ->schema([
                        Text::make(fn ($record) => new HtmlString(
                            '
                                <table class="min-w-full divide-y divide-gray-200 dark:divide-white/10">
                                    <thead class="bg-gray-50 dark:bg-white/5">
                                        <tr>
                                            <th class="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider w-1/3">Oszlop</th>
                                            <th class="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Érték</th>
                                        </tr>
                                    </thead>
                                    <tbody class="bg-white dark:bg-transparent divide-y divide-gray-200 dark:divide-white/10">
                                        ' . collect($record->payload ?? [])->map(function ($value, $key) {
                                            $valStr = is_array($value) ? json_encode($value) : (string)$value;
                                            return '<tr>
                                                <td class="px-3 py-2 text-sm text-gray-500 dark:text-gray-400 font-medium bg-gray-50/50 dark:bg-white/5">' . e($key) . '</td>
                                                <td class="px-3 py-2 text-sm text-gray-900 dark:text-gray-200 whitespace-normal break-words">' . e($valStr) . '</td>
                                            </tr>';
                                        })->join('') . '
                                    </tbody>
                                </table>
                            '
                        )),
                    ])
                    ->columnSpan(fn ($record) => (empty($record->diff) && empty($record->validation_messages)) ? 2 : 1),
            ]);
    }

    public function table(Table $table): Table
    {
        return $table
            ->recordTitleAttribute('id')
            ->columns([
                TextColumn::make('row_number')
                    ->label('#')
                    ->sortable()
                    ->width('50px'),

                TextColumn::make('status')
                    ->label('Státusz')
                    ->badge()
                    ->color(fn (PricelistFileLineStatusEnum $state) => $state->color())
                    ->formatStateUsing(fn (PricelistFileLineStatusEnum $state) => $state->label())
                    ->icon(fn (PricelistFileLineStatusEnum $state) => $state->icon())
                    ->sortable(),

                TextColumn::make('product_info')
                    ->label('Termék')
                    ->description(fn ($record) => $record->payload[PriceListService::EXPECTED_HEADERS[4]] ?? '')
                    ->getStateUsing(fn ($record) => $record->payload[PriceListService::EXPECTED_HEADERS[0]] ?? 'N/A')
                    ->color(fn ($record) => !empty($record->diff) ? 'info' : null)
                    ->wrap()
                    ->searchable(query: function ($query, string $search) {
                        $sku = PriceListService::EXPECTED_HEADERS[0];
                        $name = PriceListService::EXPECTED_HEADERS[4];
                        $query->where("payload->$sku", 'like', "%{$search}%")
                            ->orWhere("payload->$name", 'like', "%{$search}%");
                    }),


                TextColumn::make('price_diff')
                    ->label('Árváltozás')
                    ->html()
                    ->getStateUsing(function ($record) {
                        // Biztonságos elérés data_get-tel, mert a diff lehet null
                        $oldPrice = data_get($record->diff, 'price.old');

                        // Az új árat a diff-ből vesszük (már float), vagy a payload-ból (string lehet)
                        $newPriceRaw = data_get($record->diff, 'price.new') ?? data_get($record->payload, PriceListService::EXPECTED_HEADERS[14]);

                        // Normalizálás: szóközök eltávolítása és tizedesvessző cseréje
                        $newPrice = is_string($newPriceRaw)
                            ? (float) str_replace([' ', ','], ['', '.'], $newPriceRaw)
                            : (float) $newPriceRaw;

                        // Ha nincs régi ár, vagy az nulla, akkor nincs százalékos számítás
                        if (empty($oldPrice) || (float)$oldPrice === 0.0) {
                            return number_format($newPrice, 2, ',', ' ') . ' Ft';
                        }

                        $oldPrice = (float) $oldPrice;
                        $diffPercent = (($newPrice / $oldPrice) - 1) * 100;

                        $colorClass = $diffPercent > 0 ? 'text-danger-600' : ($diffPercent < 0 ? 'text-success-600' : 'text-gray-600');
                        $icon = $diffPercent > 0 ? '↑' : ($diffPercent < 0 ? '↓' : '');

                        return sprintf(
                            '<div class="flex flex-col">
                                <span class="text-xs text-gray-500 line-through">%s Ft</span>
                                <span class="font-bold">%s Ft <span class="%s">%s %s%%</span></span>
                            </div>',
                            number_format($oldPrice, 2, ',', ' '),
                            number_format($newPrice, 2, ',', ' '),
                            $colorClass,
                            $icon,
                            number_format(abs($diffPercent), 1, ',', ' ')
                        );
                    })
                    ->visible(fn ($livewire) => $livewire->getOwnerRecord()->status !== PricelistFileStatusEnum::todo),

                TextColumn::make('validation_messages')
                    ->label('Megjegyzés')
                    ->listWithLineBreaks()
                    ->bulleted()
                    ->wrap()
                    ->color(fn ($state) => collect($state)->contains(fn ($msg) => str_contains($msg, 'Hiányzó') || str_contains($msg, 'Ismeretlen') || str_contains($msg, 'Érvénytelen')) ? 'danger' : 'info')
                    ->getStateUsing(function ($record) {
                        $messages = collect($record->validation_messages ?? [])->values();

                        $diffMessages = collect($record->diff ?? [])->map(function ($d, $field) {
                            $label = $d['label'] ?? $field;
                            $old = $d['old_label'] ?? $d['old'] ?? 'N/A';
                            $new = $d['new_label'] ?? $d['new'] ?? 'N/A';

                            if ($field === 'price') {
                                $old = number_format((float)($d['old'] ?? 0), 0, ',', ' ') . ' Ft';
                                $new = number_format((float)($d['new'] ?? 0), 0, ',', ' ') . ' Ft';
                            }

                            return "Módosult $label: $old -> $new";
                        })->values();

                        return $messages->merge($diffMessages)->toArray();
                    }),
            ])
            ->filters([
                //
            ])
            ->headerActions([
                //
            ])
            ->actions([
                ViewAction::make()
                    ->slideOver()
                    ->modalWidth(Width::FourExtraLarge)
                    ->iconButton()
                    ->modalHeading(fn ($record) => "Sor száma: #{$record->row_number}")
                    ->modalDescription(fn ($record) => "Státusz: " . $record->status->label()),
            ])
            ->bulkActions([
                //
            ])
            ->defaultSort('row_number', 'asc')
            ->striped()
            ->poll('5s');
    }
}
