"""Album naming and grouping helpers used by import flows."""

from __future__ import annotations

import re
import threading
from typing import Any, Dict

from core.imports.context import extract_artist_name
from utils.logging_config import get_logger


logger = get_logger("imports.album_naming")

_album_cache_lock = threading.Lock()
_album_editions: dict[str, str] = {}
_album_name_cache: dict[str, str] = {}


def clear_album_grouping_cache() -> None:
    """Clear cached album grouping decisions.

    Useful for tests and for any future config reload flows.
    """
    with _album_cache_lock:
        _album_editions.clear()
        _album_name_cache.clear()


def get_base_album_name(album_name: str) -> str:
    """Extract the base album name without edition indicators."""
    base_name = album_name or ""
    base_name = re.sub(
        r"\s*[\[\(][^)\]]*\b(deluxe|special|expanded|extended|bonus|remaster(?:ed)?|anniversary|collectors?|limited|silver|gold|platinum)\b[^)\]]*[\]\)]\s*$",
        "",
        base_name,
        flags=re.IGNORECASE,
    )
    base_name = re.sub(r"\s*[\[\(][^)\]]*\bedition\b[^)\]]*[\]\)]\s*$", "", base_name, flags=re.IGNORECASE)
    base_name = re.sub(
        r"\s+(deluxe|special|expanded|extended|bonus|remastered|anniversary|collectors?|limited|silver|gold|platinum)\s*(edition)?\s*$",
        "",
        base_name,
        flags=re.IGNORECASE,
    )
    return base_name.strip()


def detect_deluxe_edition(album_name: str) -> bool:
    """Detect if an album name indicates a deluxe/special edition."""
    if not album_name:
        return False

    album_lower = album_name.lower()
    deluxe_indicators = [
        "deluxe",
        "deluxe edition",
        "special edition",
        "expanded edition",
        "extended edition",
        "bonus",
        "remastered",
        "anniversary",
        "collectors edition",
        "limited edition",
        "silver edition",
        "gold edition",
        "platinum edition",
    ]
    for indicator in deluxe_indicators:
        if indicator in album_lower:
            logger.info("Detected deluxe edition: %r contains %r", album_name, indicator)
            return True
    return False


def normalize_base_album_name(base_album: str, artist_name: str) -> str:
    """Normalize the base album name to handle case variations and known corrections."""
    normalized_lower = (base_album or "").lower().strip()
    known_corrections = {
        # Add specific album name corrections here as needed.
    }

    for variant, correction in known_corrections.items():
        if normalized_lower == variant.lower():
            logger.info("Album correction applied: %r -> %r", base_album, correction)
            return correction

    normalized = base_album or ""
    normalized = re.sub(r"\s*&\s*", " & ", normalized)
    normalized = re.sub(r"\s+", " ", normalized)
    normalized = normalized.strip()
    logger.info("Album variant normalization: %r -> %r", base_album, normalized)
    return normalized


def clean_album_title(album_title: str, artist_name: str) -> str:
    """Clean up album title by removing common prefixes, suffixes, and artist redundancy."""
    original = (album_title or "").strip()
    cleaned = original
    logger.info("Album Title Cleaning: %r (artist: %r)", original, artist_name)

    cleaned = re.sub(r"^Album\s*-\s*", "", cleaned, flags=re.IGNORECASE)
    artist_pattern = re.escape(artist_name or "") + r"\s*-\s*"
    cleaned = re.sub(f"^{artist_pattern}", "", cleaned, flags=re.IGNORECASE)
    cleaned = re.sub(r"\s*[\[\(]\d{4}[\]\)]\s*", " ", cleaned)

    quality_patterns = [
        r"\s*[\[\(].*?320.*?kbps.*?[\]\)]\s*",
        r"\s*[\[\(].*?256.*?kbps.*?[\]\)]\s*",
        r"\s*[\[\(].*?flac.*?[\]\)]\s*",
        r"\s*[\[\(].*?mp3.*?[\]\)]\s*",
        r"\s*[\[\(].*?itunes.*?[\]\)]\s*",
        r"\s*[\[\(].*?web.*?[\]\)]\s*",
        r"\s*[\[\(].*?cd.*?[\]\)]\s*",
    ]
    for pattern in quality_patterns:
        cleaned = re.sub(pattern, " ", cleaned, flags=re.IGNORECASE)

    cleaned = re.sub(r"\s*[\[\(][^\]\)]*\b(deluxe|special|expanded|extended|bonus|remaster(?:ed)?|anniversary|collectors?|limited|silver|gold|platinum)\b[^\]\)]*[\]\)]\s*", " ", cleaned, flags=re.IGNORECASE)
    cleaned = re.sub(r"\s*[\[\(][^\]\)]*\bedition\b[^\]\)]*[\]\)]\s*", " ", cleaned, flags=re.IGNORECASE)
    cleaned = re.sub(r"\s*(deluxe|special|expanded|extended|bonus|remastered|anniversary|collectors?|limited|silver|gold|platinum)\s*(edition)?\s*$", "", cleaned, flags=re.IGNORECASE)
    cleaned = re.sub(r"^[-\s\.]+", "", cleaned)
    cleaned = re.sub(r"[-\s\.]+$", "", cleaned)
    cleaned = re.sub(r"\s+", " ", cleaned).strip()
    return cleaned if cleaned else original


def resolve_album_group(artist_context: dict, album_info: dict, original_album: str = None) -> str:
    """Smart album grouping: upgrade to deluxe if any track is deluxe."""
    try:
        with _album_cache_lock:
            artist_name = extract_artist_name(artist_context)
            detected_album = (album_info or {}).get("album_name", "")

            if detected_album:
                base_album = get_base_album_name(detected_album)
            elif original_album:
                cleaned_original = clean_album_title(original_album, artist_name)
                base_album = get_base_album_name(cleaned_original)
            else:
                base_album = get_base_album_name(detected_album)

            base_album = normalize_base_album_name(base_album, artist_name)
            album_key = f"{artist_name}::{base_album}"
            is_deluxe_track = False
            if detected_album:
                is_deluxe_track = detect_deluxe_edition(detected_album)
            elif original_album:
                is_deluxe_track = detect_deluxe_edition(original_album)

            if album_key in _album_name_cache:
                cached_name = _album_name_cache[album_key]
                current_edition = _album_editions.get(album_key, "standard")
                if is_deluxe_track and current_edition == "standard":
                    final_album_name = f"{base_album} (Deluxe Edition)"
                    _album_editions[album_key] = "deluxe"
                    _album_name_cache[album_key] = final_album_name
                    logger.info("Album cache upgrade: %r -> %r", album_key, final_album_name)
                    return final_album_name
                logger.info("Using cached album name for %r: %r", album_key, cached_name)
                return cached_name

            logger.info("Album grouping - Key: %r, Detected: %r", album_key, detected_album)

            current_edition = _album_editions.get(album_key, "standard")
            if is_deluxe_track and current_edition == "standard":
                logger.info("UPGRADE: Album %r upgraded from standard to deluxe!", base_album)
                _album_editions[album_key] = "deluxe"
                current_edition = "deluxe"

            if current_edition == "deluxe":
                final_album_name = f"{base_album} (Deluxe Edition)"
            else:
                final_album_name = base_album

            _album_name_cache[album_key] = final_album_name

            logger.info("Album resolution: %r -> %r (edition: %s)", detected_album, final_album_name, current_edition)
            return final_album_name
    except Exception as e:
        logger.error("Error resolving album group: %s", e)
        album_name = (album_info or {}).get("album_name", "Unknown Album")
        return album_name
