<?php

namespace App\Console\Commands;

use App\Models\Anime;
use App\Models\Genre;
use App\Services\DeepSeekService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class FillAnimeMeta extends Command
{
    protected $signature = 'animexe:fill-anime-meta
                            {--limit=0    : Max anime sayısı (0 = sınırsız, hepsi)}
                            {--anime=     : Sadece belirli bir anime ID işle}
                            {--force      : Dolu alanlar olsa bile yeniden doldur}
                            {--dry-run    : Gerçekten kaydetme, sadece ne yapılacağını göster}';

    protected $description = 'Eksik meta verisi olan animeleri DeepSeek AI ile toplu doldurur (description, genres, studio, year, vb.)';

    public function handle(DeepSeekService $ai): int
    {
        // PHP zaman aşımını kaldır — tüm animeler işlenene kadar çalışsın
        set_time_limit(0);

        if (!$ai->isConfigured()) {
            $this->error('DeepSeek API anahtarı ayarlanmamış. Admin > Ayarlar > deepseek_api_key');
            return self::FAILURE;
        }

        $limit   = (int) $this->option('limit');
        $animeId = $this->option('anime');
        $force   = $this->option('force');
        $dry     = $this->option('dry-run');

        // İşlenecek animeleri belirle
        if ($animeId) {
            $animes = Anime::where('id', $animeId)->with('genres')->get();
        } else {
            $query = Anime::with('genres');

            if (!$force) {
                $query->where(function ($q) {
                    $q->whereNull('description')->orWhere('description', '')
                      ->orWhereNull('release_year')
                      ->orWhereNull('studio')->orWhere('studio', '')
                      ->orWhereNull('type')->orWhere('type', '')
                      ->orWhereNull('status')->orWhere('status', '');
                })->orDoesntHave('genres');
            }

            $query->orderBy('id');
            if ($limit > 0) $query->limit($limit);
            $animes = $query->get();
        }

        if ($animes->isEmpty()) {
            $this->info('İşlenecek anime bulunamadı (tüm alanlar dolu).');
            Log::channel('daily')->info('[FillAnimeMeta] İşlenecek anime yok.');
            return self::SUCCESS;
        }

        $this->info("Toplam {$animes->count()} anime işlenecek" . ($dry ? ' (dry-run)' : '') . '...');
        Log::channel('daily')->info("[FillAnimeMeta] Başladı. {$animes->count()} anime, limit={$limit}, force=" . ($force ? 'evet' : 'hayır'));

        $done = 0;
        $skipped = 0;
        $failed  = 0;

        foreach ($animes as $anime) {
            $missing = $this->missingFields($anime);

            if (!$force && empty($missing)) {
                $this->line("  <fg=gray>ATLA</> {$anime->title} — tüm alanlar dolu");
                $skipped++;
                continue;
            }

            $label = $force ? 'tüm alanlar' : implode(', ', $missing);
            $this->line("  <fg=cyan>İŞLE</> [{$anime->id}] {$anime->title} — eksik: {$label}");

            if ($dry) {
                $done++;
                continue;
            }

            $meta = $ai->generateAnimeMeta($anime->title, $anime->title_jp ?? '');

            if (!$meta) {
                $this->warn("  <fg=red>HATA</> {$anime->title} — AI boş yanıt döndürdü");
                Log::channel('daily')->warning("[FillAnimeMeta] HATA [{$anime->id}] {$anime->title}: AI boş yanıt");
                $failed++;
                sleep(3);
                continue;
            }

            // Sadece boş alanları doldur (force modunda hepsini güncelle)
            $updates = [];

            $fillIfEmpty = function (string $field, $value) use ($anime, $force, &$updates) {
                if ($value === null || $value === '') return;
                if ($force || empty($anime->$field)) {
                    $updates[$field] = $value;
                }
            };

            $fillIfEmpty('description',  $meta['description']  ?? null);
            $fillIfEmpty('release_year', $meta['release_year'] ?? null);
            $fillIfEmpty('studio',       $meta['studio']       ?? null);
            $fillIfEmpty('type',         $meta['type']         ?? null);
            $fillIfEmpty('status',       $meta['status']       ?? null);
            $fillIfEmpty('title_en',     $meta['title_en']     ?? null);
            $fillIfEmpty('title_jp',     $meta['title_jp']     ?? null);

            // Rating: sadece boşsa veya 0 ise doldur
            if (!empty($meta['rating']) && ($force || !$anime->rating)) {
                $updates['rating'] = min(10, max(0, (float) $meta['rating']));
            }

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

            // Genres: boşsa ekle
            if (!empty($meta['genres']) && ($force || $anime->genres->isEmpty())) {
                $genreIds = [];
                foreach ($meta['genres'] as $genreName) {
                    $genre = Genre::firstOrCreate(
                        ['name' => $genreName],
                        ['slug' => \Illuminate\Support\Str::slug($genreName)]
                    );
                    $genreIds[] = $genre->id;
                }
                if ($genreIds) {
                    $force ? $anime->genres()->sync($genreIds) : $anime->genres()->syncWithoutDetaching($genreIds);
                }
            }

            $updatedFields = array_keys($updates);
            if (!empty($meta['genres']) && ($force || $anime->genres->isEmpty())) {
                $updatedFields[] = 'genres(' . implode(',', $meta['genres'] ?? []) . ')';
            }

            $summary = empty($updatedFields) ? 'Yeni alan yok' : implode(', ', $updatedFields);
            $this->info("  <fg=green>✓ OK</> [{$anime->id}] {$anime->title} → {$summary}");
            Log::channel('daily')->info("[FillAnimeMeta] OK [{$anime->id}] {$anime->title} → {$summary}");

            $done++;

            // API rate limit — DeepSeek'i boğma
            sleep(2);
        }

        $summary = "Tamamlandı: {$done} işlendi, {$skipped} atlandı, {$failed} hata.";
        $this->info($summary);
        Log::channel('daily')->info("[FillAnimeMeta] {$summary}");

        return $failed > 0 ? self::FAILURE : self::SUCCESS;
    }

    private function missingFields(Anime $anime): array
    {
        $missing = [];
        if (empty($anime->description))  $missing[] = 'description';
        if (empty($anime->release_year)) $missing[] = 'release_year';
        if (empty($anime->studio))       $missing[] = 'studio';
        if (empty($anime->type))         $missing[] = 'type';
        if (empty($anime->status))       $missing[] = 'status';
        if (!$anime->rating)             $missing[] = 'rating';
        if (empty($anime->title_en))     $missing[] = 'title_en';
        if ($anime->genres->isEmpty())   $missing[] = 'genres';
        return $missing;
    }
}
