<?php

namespace Database\Seeders;

use App\Models\Category;
use App\Models\Course;
use App\Models\CourseBlock;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;

class CourseContentSeeder extends Seeder
{
    /**
     * Seed course blocks (rich content) from parsed docx articles.
     * Updates long_desc/requirements/scope on existing courses if empty.
     * Creates new courses from articles that don't match existing ones.
     *
     * Source: storage/app/course_blocks_data.json
     * Run AFTER CourseSeeder. Existing CourseSeeder is untouched.
     */
    public function run(): void
    {
        $jsonPath = storage_path('app/course_blocks_data.json');

        if (! file_exists($jsonPath)) {
            $this->command->error('course_blocks_data.json bulunamadı. Önce Python parse script çalıştırın.');

            return;
        }

        /** @var array<int, array<string, mixed>> $data */
        $data = json_decode(file_get_contents($jsonPath), true);
        $cats = Category::pluck('id', 'slug');
        $allCourses = Course::all();
        $matched = 0;
        $created = 0;
        $newCourses = 0;
        $blockCount = 0;

        foreach ($data as $item) {
            $course = $this->findCourse($allCourses, $item);

            if (! $course) {
                // Create new course from article data
                $categoryId = $cats[$item['category_slug']] ?? null;
                if (! $categoryId) {
                    $this->command->warn("Kategori bulunamadı: {$item['category_slug']} -> {$item['title_short']}");

                    continue;
                }

                $course = Course::create([
                    'category_id' => $categoryId,
                    'slug' => Str::slug($item['title_short']),
                    'title' => $item['title_short'],
                    'desc' => Str::limit($item['long_desc'], 200),
                    'long_desc' => $item['long_desc'],
                    'duration' => '',
                    'requirements' => $item['requirements'],
                    'scope' => $item['scope'],
                    'standard' => 'STCW / IMO Uyumlu',
                    'language' => 'Türkçe',
                    'location' => 'Kadıköy, İstanbul',
                    'meta_title' => $item['title_short'].' | Boğaziçi Denizcilik',
                    'meta_description' => Str::limit($item['long_desc'], 155),
                ]);
                $newCourses++;
                $allCourses->push($course);
            } else {
                $matched++;
                $this->updateCourseFields($course, $item);
            }

            // Sync blocks
            $count = $this->syncBlocks($course, $item['blocks']);
            $blockCount += $count;
        }

        $total = count($data);
        $this->command->info("Toplam: {$total} makale, {$matched} eşleşme, {$newCourses} yeni kurs, {$blockCount} blok.");
    }

    /**
     * @param  Collection<int, Course>  $allCourses
     * @param  array<string, mixed>  $item
     */
    private function findCourse($allCourses, array $item): ?Course
    {
        $articleSlug = Str::slug($item['title_short']);
        $titleNorm = $this->normalize($item['title_short']);

        // 1. Exact slug match
        $found = $allCourses->first(fn (Course $c) => $c->slug === $articleSlug);
        if ($found) {
            return $found;
        }

        // 2. Normalized title contains match
        $found = $allCourses->first(fn (Course $c) => $this->normalize($c->title) === $titleNorm);
        if ($found) {
            return $found;
        }

        // 3. Fuzzy — first 25 chars of normalized title
        $prefix = mb_substr($titleNorm, 0, 25);

        return $allCourses->first(fn (Course $c) => str_starts_with($this->normalize($c->title), $prefix));
    }

    /**
     * Normalize text: lowercase, strip accents, collapse whitespace.
     */
    private function normalize(string $text): string
    {
        $text = mb_strtolower($text);
        // Turkish specific replacements
        $text = str_replace(
            ['ç', 'ğ', 'ı', 'ö', 'ş', 'ü', 'â', 'î', 'û'],
            ['c', 'g', 'i', 'o', 's', 'u', 'a', 'i', 'u'],
            $text,
        );
        $text = preg_replace('/[^a-z0-9\s]/', '', $text);

        return preg_replace('/\s+/', ' ', trim($text));
    }

    /**
     * @param  array<string, mixed>  $item
     */
    private function updateCourseFields(Course $course, array $item): void
    {
        $updates = [];

        if (empty($course->long_desc) && ! empty($item['long_desc'])) {
            $updates['long_desc'] = $item['long_desc'];
        }

        if ((empty($course->requirements) || $course->requirements === []) && ! empty($item['requirements'])) {
            $updates['requirements'] = $item['requirements'];
        }

        if ((empty($course->scope) || $course->scope === []) && ! empty($item['scope'])) {
            $updates['scope'] = $item['scope'];
        }

        if (! empty($updates)) {
            $course->update($updates);
        }
    }

    /**
     * @param  array<int, array<string, mixed>>  $blocks
     */
    private function syncBlocks(Course $course, array $blocks): int
    {
        $count = 0;

        foreach ($blocks as $block) {
            CourseBlock::updateOrCreate(
                ['course_id' => $course->id, 'order_index' => $block['order_index']],
                ['type' => $block['type'], 'content' => $block['content']],
            );
            $count++;
        }

        return $count;
    }
}
