"""Sitemap status checking and resubmission."""

from __future__ import annotations

import logging
import time

from googleapiclient.errors import HttpError

from src.api.rate_limiter import RateLimiter, retry_on_api_error
from src.models.data_models import SitemapStatus

logger = logging.getLogger("seo_optimizer")


@retry_on_api_error()
def _list_sitemaps(service, site_url: str) -> list[dict]:
    """List all submitted sitemaps for a site."""
    response = service.sitemaps().list(siteUrl=site_url).execute()
    return response.get("sitemap", [])


@retry_on_api_error()
def _submit_sitemap(service, site_url: str, sitemap_url: str) -> None:
    """Submit (or resubmit) a sitemap."""
    service.sitemaps().submit(siteUrl=site_url, feedpath=sitemap_url).execute()


def get_sitemap_statuses(
    service,
    site_url: str,
    rate_limiter: RateLimiter | None = None,
) -> list[SitemapStatus]:
    """Get status of all submitted sitemaps for a site.

    Returns:
        List of SitemapStatus objects.
    """
    if rate_limiter:
        rate_limiter.acquire(site_url)

    raw_sitemaps = _list_sitemaps(service, site_url)
    statuses = []

    for sm in raw_sitemaps:
        status = SitemapStatus(
            path=sm.get("path", ""),
            last_submitted=sm.get("lastSubmitted", ""),
            last_downloaded=sm.get("lastDownloaded", ""),
            is_pending=sm.get("isPending", False),
            is_sitemaps_index=sm.get("isSitemapsIndex", False),
            warnings=sm.get("warnings", 0),
            errors=sm.get("errors", 0),
            contents=sm.get("contents", []),
        )
        statuses.append(status)

    logger.info(
        "Found %d sitemaps for %s", len(statuses), site_url,
    )
    return statuses


def resubmit_sitemap(
    service,
    site_url: str,
    sitemap_url: str,
    max_retries: int = 3,
    rate_limiter: RateLimiter | None = None,
) -> bool:
    """Resubmit a sitemap with retries.

    Returns:
        True if resubmission succeeded, False otherwise.
    """
    for attempt in range(1, max_retries + 1):
        try:
            if rate_limiter:
                rate_limiter.acquire(site_url)

            _submit_sitemap(service, site_url, sitemap_url)
            logger.info(
                "Sitemap resubmitted successfully: %s (attempt %d)",
                sitemap_url, attempt,
            )
            return True
        except HttpError as e:
            logger.warning(
                "Sitemap resubmission failed: %s (attempt %d/%d): %s",
                sitemap_url, attempt, max_retries, e,
            )
            if attempt < max_retries:
                time.sleep(2 ** attempt)

    return False


def check_and_resubmit(
    service,
    site_url: str,
    known_sitemap_urls: list[str],
    max_retries: int = 3,
    rate_limiter: RateLimiter | None = None,
) -> list[SitemapStatus]:
    """Check sitemap statuses and resubmit those with errors.

    Args:
        service: Webmasters v3 service.
        site_url: GSC property URL.
        known_sitemap_urls: Expected sitemap URLs from config.
        max_retries: Max resubmission attempts per sitemap.
        rate_limiter: Optional rate limiter.

    Returns:
        Updated list of SitemapStatus after resubmission attempts.
    """
    statuses = get_sitemap_statuses(service, site_url, rate_limiter)

    submitted_paths = {s.path for s in statuses}

    # Submit any known sitemaps not yet submitted
    for url in known_sitemap_urls:
        if url not in submitted_paths:
            logger.info("Submitting new sitemap: %s", url)
            resubmit_sitemap(service, site_url, url, max_retries, rate_limiter)

    # Resubmit sitemaps with errors
    for status in statuses:
        if status.errors > 0:
            logger.warning(
                "Sitemap has errors (%d): %s — resubmitting",
                status.errors, status.path,
            )
            resubmit_sitemap(
                service, site_url, status.path, max_retries, rate_limiter,
            )

    # Re-fetch statuses after resubmission
    updated_statuses = get_sitemap_statuses(service, site_url, rate_limiter)
    return updated_statuses
