<?php

namespace App\Filament\Resources\Manage\DataChanges\Infolists;

use App\Filament\Support\CheerfulNotification;
use App\Models\DataChangeRequest;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Illuminate\Support\Facades\Storage;

class DataChangeInfolist
{
    public static function configure(Schema $schema): Schema
    {
        return $schema
            ->schema([
                Section::make()
                    ->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 self::alert('Format data tidak valid.', 'warning');
                                }

                                if (isset($new['__delete_request__']) && $new['__delete_request__'] === true) {
                                    return self::deletionView($old);
                                }

                                if (empty($old)) {
                                    return self::additionView($new);
                                }

                                return self::updateView($old, $new);
                            }),
                    ]),
            ])
            ->columns(1);
    }

    private static function deletionView(array $old): string
    {
        $title = CheerfulNotification::getByKey('data_change.deletion_request_title');
        $desc = CheerfulNotification::getByKey('data_change.deletion_request_desc');

        $rows = collect($old)
            ->map(fn ($v, $k) => self::row($k, self::renderValue($v)))
            ->implode('');

        return self::card(
            header: self::header('del', $title, $desc, self::badge('Penghapusan', 'del')),
            body: $rows ?: self::emptyRow(),
        );
    }

    private static function additionView(array $new): string
    {
        $title = CheerfulNotification::getByKey('data_change.addition_request_title');
        $desc = CheerfulNotification::getByKey('data_change.addition_request_desc');

        $rows = collect($new)
            ->map(fn ($v, $k) => self::row($k, self::renderValue($v)))
            ->implode('');

        return self::card(
            header: self::header('add', $title, $desc, self::badge('Penambahan Baru', 'add')),
            body: $rows ?: self::emptyRow(),
        );
    }

    private static function updateView(array $old, array $new): string
    {
        $changed = collect($new)
            ->map(function ($newVal, $key) use ($old) {
                $oldVal = $old[$key] ?? null;

                if ($oldVal === $newVal) {
                    return null;
                }

                return "
                    <div style='display:grid; grid-template-columns:180px 1fr; border-bottom:1px solid var(--dcr-row-border); align-items:stretch;'>
                        <div style='padding:11px 14px; font-size:0.75rem; font-weight:500; color:var(--dcr-key-color); letter-spacing:0.025em; background:var(--dcr-key-bg); border-right:1px solid var(--dcr-key-border); display:flex; align-items:center; word-break:break-word;'>".e($key)."</div>
                        <div style='display:grid; grid-template-columns:1fr 1fr;'>
                            <div style='padding:11px 14px; background:var(--dcr-old-bg); border-right:1px solid var(--dcr-old-border); color:var(--dcr-old-color); word-break:break-word; font-size:0.8125rem;'>".self::renderValue($oldVal)."</div>
                            <div style='padding:11px 14px; background:var(--dcr-new-bg); color:var(--dcr-new-color); word-break:break-word; font-size:0.8125rem;'>".self::renderValue($newVal).'</div>
                        </div>
                    </div>';
            })
            ->filter();

        if ($changed->isEmpty()) {
            return self::alert('Tidak ada perubahan data yang terdeteksi.', 'info');
        }

        $count = $changed->count();
        $label = $count === 1 ? '1 field diubah' : "{$count} field diubah";

        $diffHeader = "
            <div style='display:grid; grid-template-columns:180px 1fr;'>
                <div style='padding:8px 14px; background:var(--dcr-key-bg); border-right:1px solid var(--dcr-key-border); border-bottom:1px solid var(--dcr-header-border);'></div>
                <div style='display:grid; grid-template-columns:1fr 1fr; border-bottom:1px solid var(--dcr-header-border);'>
                    <div style='padding:8px 14px; font-size:0.7rem; font-weight:600; color:var(--dcr-key-color); text-transform:uppercase; letter-spacing:0.06em; background:var(--dcr-old-bg); border-right:1px solid var(--dcr-old-border);'>Sebelum</div>
                    <div style='padding:8px 14px; font-size:0.7rem; font-weight:600; color:var(--dcr-key-color); text-transform:uppercase; letter-spacing:0.06em; background:var(--dcr-new-bg);'>Sesudah</div>
                </div>
            </div>";

        return self::card(
            header: self::header('edit', CheerfulNotification::getByKey('data_change.comparison_title'), CheerfulNotification::getByKey('data_change.comparison_desc'), self::badge($label, 'default')),
            body: $diffHeader.$changed->implode(''),
        );
    }

    private static function card(string $header, string $body): string
    {
        return "
            <div style='border:1px solid var(--dcr-border); border-radius:var(--c-border-radius); overflow:hidden; background:var(--dcr-bg); font-family:var(--font-family,Inter,ui-sans-serif,sans-serif); font-size:0.8125rem;'>
                {$header}
                <div>{$body}</div>
            </div>";
    }

    private static function header(string $type, string $title, string $desc, string $badge): string
    {
        $icon = self::icon($type);

        return "
            <div style='padding:14px 18px; background:var(--dcr-header-bg); border-bottom:1px solid var(--dcr-header-border); display:flex; align-items:center; gap:10px;'>
                {$icon}
                <div style='flex:1; min-width:0;'>
                    <div style='font-size:0.875rem; font-weight:600; color:var(--dcr-title); line-height:1.4;'>{$title}</div>
                    <div style='font-size:0.75rem; color:var(--dcr-desc); margin-top:1px;'>{$desc}</div>
                </div>
                {$badge}
            </div>";
    }

    private static function row(string $key, string $value): string
    {
        return "
            <div style='display:grid; grid-template-columns:180px 1fr; border-bottom:1px solid var(--dcr-row-border);'>
                <div style='padding:11px 14px; font-size:0.75rem; font-weight:500; color:var(--dcr-key-color); letter-spacing:0.025em; background:var(--dcr-key-bg); border-right:1px solid var(--dcr-key-border); display:flex; align-items:flex-start; word-break:break-word;'>".e($key)."</div>
                <div style='padding:11px 14px; color:var(--dcr-val-color); word-break:break-word;'>{$value}</div>
            </div>";
    }

    private static function emptyRow(): string
    {
        return "<div style='padding:18px; font-size:0.8125rem; color:var(--dcr-muted); font-style:italic;'>Tidak ada data tersedia.</div>";
    }

    private static function badge(string $label, string $variant): string
    {
        [$bg, $color, $border] = match ($variant) {
            'del' => ['var(--dcr-badge-del-bg)', 'var(--dcr-badge-del-color)', 'var(--dcr-badge-del-border)'],
            'add' => ['var(--dcr-badge-add-bg)', 'var(--dcr-badge-add-color)', 'var(--dcr-badge-add-border)'],
            default => ['var(--dcr-badge-bg)',     'var(--dcr-badge-color)',     'var(--dcr-badge-border)'],
        };

        return "<span style='display:inline-flex; align-items:center; border-radius:var(--c-border-radius); padding:2px 8px; font-size:0.7rem; font-weight:600; letter-spacing:0.025em; white-space:nowrap; background:{$bg}; color:{$color}; border:1px solid {$border};'>{$label}</span>";
    }

    private static function alert(string $message, string $type = 'info'): string
    {
        $icon = $type === 'warning' ? '⚠' : 'ℹ';

        return "
            <div style='background:var(--dcr-alert-bg); border:1px solid var(--dcr-alert-border); border-radius:var(--c-border-radius); padding:14px 16px; display:flex; align-items:flex-start; gap:10px; font-family:var(--font-family,Inter,ui-sans-serif,sans-serif);'>
                <span style='color:var(--dcr-alert-color); font-size:0.875rem; margin-top:1px; flex-shrink:0;'>{$icon}</span>
                <span style='color:var(--dcr-alert-color); font-size:0.8125rem; font-weight:500;'>{$message}</span>
            </div>";
    }

    private static function icon(string $type): string
    {
        return match ($type) {
            'del' => "<svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='var(--dcr-icon-del)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' style='flex-shrink:0'><polyline points='3 6 5 6 21 6'/><path d='M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6'/><path d='M10 11v6M14 11v6'/><path d='M9 6V4h6v2'/></svg>",
            'add' => "<svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='var(--dcr-icon-add)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' style='flex-shrink:0'><line x1='12' y1='5' x2='12' y2='19'/><line x1='5' y1='12' x2='19' y2='12'/></svg>",
            'edit' => "<svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='var(--dcr-icon-edit)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' style='flex-shrink:0'><path d='M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7'/><path d='M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z'/></svg>",
            default => '',
        };
    }

    private static function renderValue(mixed $value): string
    {
        if ($value === null || $value === '' || (is_array($value) && empty($value))) {
            return "<span style='color:var(--dcr-muted); font-size:0.8rem;'>—</span>";
        }

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

        return collect($paths)->map(function ($item) {
            if (! is_string($item)) {
                return "<span style='color:var(--dcr-val-color); font-size:0.8125rem;'>".e(json_encode($item)).'</span>';
            }

            if (preg_match('/^https?:\/\//i', $item)) {
                return "<a href='{$item}' target='_blank' style='color:var(--dcr-link); text-decoration:underline; font-size:0.8125rem; word-break:break-all;'>".e($item).'</a>';
            }

            if ((str_contains($item, '/') || str_contains($item, '\\')) && ! str_contains($item, ' ')) {
                $url = Storage::disk(config('filesystems.default'))->url($item);
                $ext = strtolower(pathinfo($item, PATHINFO_EXTENSION));

                if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'])) {
                    return "<img src='{$url}' style='max-height:96px; border-radius:var(--c-border-radius); border:1px solid var(--dcr-img-border); margin-top:4px; display:block;'>";
                }

                if ($ext === 'pdf') {
                    return "
                        <div style='margin-top:6px;'>
                            <iframe src='{$url}' style='width:100%; height:280px; border:1px solid var(--dcr-img-border); border-radius:var(--c-border-radius);'></iframe>
                        </div>";
                }

                $extUp = $ext ? strtoupper($ext) : 'FILE';

                return "<a href='{$url}' style='display:inline-flex; align-items:center; gap:4px; color:var(--dcr-link); font-size:0.8rem; font-weight:500; text-decoration:none;'>
                    <svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48'/></svg>
                    Dokumen {$extUp}
                </a>";
            }

            return "<span style='color:var(--dcr-val-color); font-size:0.8125rem;'>".e($item).'</span>';
        })->implode('<br>');
    }
}
