"""Service for updating tag collections on metadata records."""

from __future__ import annotations

import os

from typing import Awaitable, Callable, Dict, List, Sequence, Tuple

from .auto_tag_service import extract_auto_tags


class TagUpdateService:
    """Encapsulate tag manipulation for models."""

    def __init__(self, *, metadata_manager) -> None:
        self._metadata_manager = metadata_manager

    async def add_tags(
        self,
        *,
        file_path: str,
        new_tags: Sequence[str],
        metadata_loader: Callable[[str], Awaitable[Dict[str, object]]],
        update_cache: Callable[[str, str, Dict[str, object]], Awaitable[bool]],
    ) -> Tuple[List[str], List[str]]:
        """Add tags to a metadata entry and return updated tags and auto_tags."""
        base, _ = os.path.splitext(file_path)
        metadata_path = f"{base}.metadata.json"
        metadata = await metadata_loader(metadata_path)

        raw_tags = metadata.get("tags", [])
        existing_tags = list(raw_tags) if isinstance(raw_tags, list) else []
        existing_lower = [tag.lower() for tag in existing_tags]

        tags_added: List[str] = []
        for tag in new_tags:
            if isinstance(tag, str) and tag.strip():
                # Convert all tags to lowercase to avoid case sensitivity issues on Windows
                normalized = tag.strip().lower()
                if normalized not in existing_lower:
                    existing_tags.append(normalized)
                    existing_lower.append(normalized)
                    tags_added.append(normalized)

        metadata["tags"] = existing_tags
        await self._metadata_manager.save_metadata(file_path, metadata)
        await update_cache(file_path, file_path, metadata)

        auto_tags = extract_auto_tags(metadata)
        return existing_tags, auto_tags

