"""Import command - fetch notes from Anki and save as YAML files."""

from dataclasses import dataclass
import logging
from typing import Any, Dict, List, Optional

import click
from click._termui_impl import ProgressBar

from ..anki_client import AnkiClient, AnkiConnectError
from ..file_manager import FileManager
from ..models import Note
from .common import (
    log_and_print_connect_error,
    log_and_print_unexpected_error,
    temporary_log_level,
)

logger = logging.getLogger(__name__)


@dataclass
class ImportStats:
    """Tracking counters for import operations."""

    total_imported: int = 0
    errors: int = 0


def _fields_from_anki(fields: Dict[str, object]) -> Dict[str, str]:
    field_values: Dict[str, str] = {}
    for field_name, field_data in fields.items():
        if isinstance(field_data, dict):
            field_values[field_name] = str(field_data.get("value", ""))
        else:
            field_values[field_name] = str(field_data)
    return field_values


def _deck_name_from_cards(
    client: AnkiClient,
    cards: List[int],
) -> Optional[str]:
    if not cards:
        return None
    cards_info = client.get_cards_info(cards)
    if cards_info:
        return cards_info[0].get("deckName")
    return None


def _note_from_info(
    client: AnkiClient,
    note: Dict[str, Any],
) -> Note:
    note_id: int = note.get("noteId", 0)
    model_name: str = note.get("modelName", "")
    tags: List[str] = note.get("tags", [])
    fields: Dict[str, object] = note.get("fields", {})
    cards: List[int] = note.get("cards", [])

    field_values: Dict[str, str] = {}
    if isinstance(fields, dict):
        field_values = _fields_from_anki(fields)

    deck_name = None
    if isinstance(cards, list):
        deck_name = _deck_name_from_cards(client, cards)

    return Note(
        id=note_id,
        type=model_name,
        deck=deck_name,
        tags=tags,
        fields=field_values,
    )


def _import_batch(
    client: AnkiClient,
    file_manager: FileManager,
    stats: ImportStats,
    batch: List[int],
    progress_notes: ProgressBar,
) -> None:
    imported_notes = client.get_notes_info(batch)
    for imported_note in imported_notes:
        try:
            imported_note = _note_from_info(client, imported_note)
            file_manager.save_note(imported_note)
            stats.total_imported += 1
        except Exception as e:  # pylint: disable=broad-exception-caught
            logger.error(
                "Failed to import note %s: %s",
                imported_note.id if isinstance(imported_note, Note) else "unknown",
                e,
            )
            stats.errors += 1
        finally:
            progress_notes.update(1)


def import_notes(output_dir: str = "notes") -> None:
    """Import all notes from Anki and save as YAML files.

    Args:
        output_dir: Directory to save YAML files to

    Raises:
        AnkiConnectError: If connection to Anki fails
    """
    client = AnkiClient()
    file_manager = FileManager(output_dir)
    stats = ImportStats()

    try:
        note_ids = client.get_all_note_ids()
        if not note_ids:
            logger.info("No notes found in Anki")
            print("✓ No notes to import")
            return
        batch_size = 100
        progress_label = "Importing notes from Anki"
        with temporary_log_level("anki_sync", logging.WARNING):
            with click.progressbar(
                length=len(note_ids),
                label=progress_label,
            ) as progress_notes:
                for i in range(0, len(note_ids), batch_size):
                    batch = note_ids[i : i + batch_size]
                    try:
                        _import_batch(
                            client,
                            file_manager,
                            stats,
                            batch,
                            progress_notes,
                        )
                    except Exception as e:  # pylint: disable=broad-exception-caught
                        logger.error("Failed to fetch batch: %s", e)
                        stats.errors += len(batch)
                        progress_notes.update(len(batch))

        print(f"✓ Imported {stats.total_imported} notes to {output_dir}/")
        if stats.errors > 0:
            print(f"⚠ {stats.errors} notes failed to import")
    except AnkiConnectError as e:
        log_and_print_connect_error(logger, e)
        raise
    except Exception as e:
        log_and_print_unexpected_error(logger, e, "import")
        raise
