<?php

namespace App\Services\Article;

use App\Enums\ApprovalStatusEnum;
use App\Models\Article;
use App\Models\Keyword;
use App\Models\Route;
use App\Models\RouteArticle;
use App\Models\Setting;
use Illuminate\Support\Collection;

class ValidationService
{
    public function __construct(
        private ArticleFetcher $articleFetcher
    ) {}

    public function validate(Article $article): Article
    {
        logger('Validating article for routes: '.$article->id);

        $articleData = $this->articleFetcher->fetchArticleData($article);

        $updateData = [];

        if (! empty($articleData)) {
            $updateData['title'] = $articleData['title'] ?? $article->title;
            $updateData['description'] = $articleData['description'] ?? $article->description;
            $updateData['content'] = $articleData['full_article'] ?? null;
            $updateData['image_url'] = ($articleData['thumbnail'] ?? null) ?: $article->image_url;
        }

        if (! isset($articleData['full_article']) || empty($articleData['full_article'])) {
            logger()->warning('Article data missing full_article content', [
                'article_id' => $article->id,
                'url' => $article->url,
            ]);

            $updateData['validated_at'] = now();
            $article->update($updateData);

            return $article->refresh();
        }

        $updateData['validated_at'] = now();
        $article->update($updateData);

        $this->createRouteArticles($article, $articleData['full_article']);

        return $article->refresh();
    }

    private function createRouteArticles(Article $article, string $content): void
    {
        $activeRoutes = Route::where('feed_id', $article->feed_id)
            ->where('is_active', true)
            ->get();

        // Batch-load all active keywords for this feed, grouped by channel
        $keywordsByChannel = Keyword::where('feed_id', $article->feed_id)
            ->where('is_active', true)
            ->get()
            ->groupBy('platform_channel_id');

        // Match keywords against full article content, title, and description
        $searchableContent = $content.' '.$article->title.' '.$article->description;

        foreach ($activeRoutes as $route) {
            $routeKeywords = $keywordsByChannel->get($route->platform_channel_id, collect());
            $status = $this->evaluateKeywords($routeKeywords, $searchableContent);

            if ($status === ApprovalStatusEnum::PENDING && $this->shouldAutoApprove($route)) {
                $status = ApprovalStatusEnum::APPROVED;
            }

            RouteArticle::firstOrCreate(
                [
                    'feed_id' => $route->feed_id,
                    'platform_channel_id' => $route->platform_channel_id,
                    'article_id' => $article->id,
                ],
                [
                    'approval_status' => $status,
                    'validated_at' => now(),
                ]
            );
        }
    }

    /**
     * @param  Collection<int, Keyword>  $keywords
     */
    private function evaluateKeywords(Collection $keywords, string $content): ApprovalStatusEnum
    {
        if ($keywords->isEmpty()) {
            return ApprovalStatusEnum::PENDING;
        }

        foreach ($keywords as $keyword) {
            if (stripos($content, $keyword->keyword) !== false) {
                return ApprovalStatusEnum::PENDING;
            }
        }

        return ApprovalStatusEnum::REJECTED;
    }

    private function shouldAutoApprove(Route $route): bool
    {
        if ($route->auto_approve !== null) {
            return $route->auto_approve;
        }

        return ! Setting::isPublishingApprovalsEnabled();
    }
}
