"""
IndexNow: notify Bing (which powers ChatGPT search and Copilot), Yandex, Naver and
Seznam the moment an article is published or updated, instead of waiting for a crawl.
Runs in a background thread and never slows down or breaks saving in the admin.
"""
import logging
import threading

import requests
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver

from apps.core.seo import absolute, site_url

logger = logging.getLogger(__name__)
ENDPOINT = 'https://api.indexnow.org/indexnow'


def submit_urls(urls):
    key = getattr(settings, 'INDEXNOW_KEY', '')
    if not key or settings.DEBUG or not urls:
        return  # only from the live site
    payload = {
        'host': site_url().split('://', 1)[-1],
        'key': key,
        'keyLocation': absolute(f'/{key}.txt'),
        'urlList': list(dict.fromkeys(urls))[:100],
    }

    def _send():
        try:
            requests.post(ENDPOINT, json=payload, timeout=10)
        except Exception as exc:  # network problems must never affect editors
            logger.info('IndexNow ping failed: %s', exc)

    threading.Thread(target=_send, daemon=True).start()


@receiver(post_save, sender='articles.Article')
def ping_on_publish(sender, instance, **kwargs):
    if instance.status == 'published' and instance.slug:
        urls = [absolute(instance.get_absolute_url()), absolute('/')]
        urls += [absolute(f'/articles/category/{c.slug}/') for c in instance.categories.all()]
        submit_urls(urls)
