<?php

namespace App\Http\Controllers;

use App\Models\LegalPage;
use Illuminate\Database\QueryException;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Inertia\Inertia;
use Inertia\Response;
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\Autolink\AutolinkExtension;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\Strikethrough\StrikethroughExtension;
use League\CommonMark\Extension\Table\TableExtension;
use League\CommonMark\Extension\TaskList\TaskListExtension;
use League\CommonMark\MarkdownConverter;

class LegalPageController extends Controller
{
    public function show(Request $request, string $locale, ?string $slug = null): Response
    {
        $slugCandidates = $this->resolveSlugs($slug);
        $page = null;

        try {
            $page = LegalPage::query()
                ->whereIn('slug', $slugCandidates)
                ->where('is_published', true)
                ->orderByDesc('version')
                ->first();
        } catch (QueryException $exception) {
            // Table does not exist or query failed; fallback to filesystem documents
            $page = null;
        }

        $locale = $request->route('locale', app()->getLocale());

        if (! $page) {
            $fallback = $this->loadFallbackDocument($slugCandidates, $locale);

            if (! $fallback) {
                abort(404);
            }

            return Inertia::render('legal/Show', [
                'seoTitle' => $fallback['title'].' - '.config('app.name', 'Fotospiel'),
                'title' => $fallback['title'],
                'content' => $this->convertMarkdownToHtml($fallback['markdown']),
                'effectiveFrom' => null,
                'effectiveFromLabel' => null,
                'versionLabel' => null,
                'slug' => $slugCandidates[0],
            ]);
        }

        $title = $page->title[$locale]
            ?? $page->title[$page->locale_fallback]
            ?? $page->title['de']
            ?? $page->title['en']
            ?? Str::title($slugCandidates[0]);
        $title = Str::ucfirst($title);

        $bodyMarkdown = $page->body_markdown[$locale]
            ?? $page->body_markdown[$page->locale_fallback]
            ?? reset($page->body_markdown)
            ?? '';

        $effectiveFrom = optional($page->effective_from);

        return Inertia::render('legal/Show', [
            'seoTitle' => $title . ' - ' . config('app.name', 'Fotospiel'),
            'title' => $title,
            'content' => $this->convertMarkdownToHtml($bodyMarkdown),
            'effectiveFrom' => $effectiveFrom ? $effectiveFrom->toDateString() : null,
            'effectiveFromLabel' => $effectiveFrom
                ? __('legal.effective_from', ['date' => $effectiveFrom->translatedFormat('d. F Y')])
                : null,
            'versionLabel' => __('legal.version', ['version' => $page->version]),
            'slug' => $slugCandidates[0],
        ]);
    }

    private function resolveSlugs(?string $slug): array
    {
        $slug = strtolower($slug ?? '');

        $aliases = [
            'imprint' => 'impressum',
            'privacy' => 'datenschutz',
            'terms' => 'agb',
            'withdrawal' => 'widerrufsbelehrung',
            'cancellation' => 'widerrufsbelehrung',
            'cancellation-policy' => 'widerrufsbelehrung',
            'widerruf' => 'widerrufsbelehrung',
        ];

        $canonical = $aliases[$slug] ?? $slug ?: 'impressum';

        // Support both slugs for withdrawal in case DB uses a shorter slug
        $fallbacks = $canonical === 'widerrufsbelehrung'
            ? ['widerrufsbelehrung', 'widerruf']
            : [$canonical];

        return array_values(array_unique($fallbacks));
    }

    private function convertMarkdownToHtml(string $markdown): string
    {
        $environment = new Environment([
            'html_input' => 'strip',
            'allow_unsafe_links' => false,
        ]);

        $environment->addExtension(new CommonMarkCoreExtension());
        $environment->addExtension(new TableExtension());
        $environment->addExtension(new AutolinkExtension());
        $environment->addExtension(new StrikethroughExtension());
        $environment->addExtension(new TaskListExtension());

        $converter = new MarkdownConverter($environment);

        return trim((string) $converter->convert($markdown));
    }

    private function loadFallbackDocument(array $slugCandidates, string $locale): ?array
    {
        $candidates = array_unique([
            strtolower($locale),
            strtolower(config('app.fallback_locale', 'de')),
            'de',
            'en',
        ]);

        foreach ($slugCandidates as $slug) {
            foreach ($candidates as $candidateLocale) {
                $path = base_path("docs/legal/{$slug}-{$candidateLocale}.md");

                if (! is_file($path)) {
                    continue;
                }

                $markdown = (string) file_get_contents($path);
                $title = $this->extractTitleFromMarkdown($markdown) ?? Str::title($slug);

                return [
                    'markdown' => $markdown,
                    'title' => $title,
                ];
            }
        }

        return null;
    }

    private function extractTitleFromMarkdown(string $markdown): ?string
    {
        foreach (preg_split('/\r?\n/', $markdown) as $line) {
            $trimmed = trim($line);

            if ($trimmed === '') {
                continue;
            }

            if (str_starts_with($trimmed, '# ')) {
                return trim(substr($trimmed, 2));
            }

            if (str_starts_with($trimmed, '## ')) {
                return trim(substr($trimmed, 3));
            }

            // First non-empty line can act as fallback title
            return $trimmed;
        }

        return null;
    }
}
