from result import Result, Ok, Err
import requests
import logging
from typing import List, Dict

logger = logging.getLogger("flashcard-creator")

class AnkiError(Exception):
    """Base class for Anki-related errors"""
    pass

class ConnectionError(AnkiError):
    """Error connecting to AnkiConnect"""
    pass

class DeckError(AnkiError):
    """Error related to deck operations"""
    pass

class CardError(AnkiError):
    """Error related to card operations"""
    pass

class AnkiConnect:
    def __init__(self, url="http://127.0.0.1:8765"):
        self.url = url

    def get_decks(self) -> Result[List[str], AnkiError]:
        """Get the list of decks from Anki using AnkiConnect."""
        try:
            response = requests.post(
                self.url, json={"action": "deckNames", "version": 6}
            )
            data = response.json()
            return Ok(data.get("result", []))
        except requests.exceptions.RequestException as e:
            logger.error(f"Connection error getting Anki decks: {e}")
            return Err(ConnectionError(f"Failed to connect to Anki: {e}"))
        except Exception as e:
            logger.error(f"Error getting Anki decks: {e}")
            return Err(DeckError(f"Failed to get decks: {e}"))

    def create_cards(self, deck: str, cards: List[Dict[str, str]]) -> Result[bool, AnkiError]:
        """Create flashcards in Anki using AnkiConnect."""
        try:
            # Prepare notes for addition
            notes = []
            logger.info(f"Preparing to create {len(cards)} Anki cards in deck: {deck}")
            for card in cards:
                notes.append(
                    {
                        "deckName": deck,
                        "modelName": "Basic",  # Using the basic model
                        "fields": {"Front": card["front"], "Back": card["back"]},
                        "options": {"allowDuplicate": False},
                        "tags": [f"{self.source_language}-{self.target_language}"],
                    }
                )

            # Add notes to Anki
            logger.info("Sending request to AnkiConnect to add notes")
            response = requests.post(
                self.url,
                json={"action": "addNotes", "version": 6, "params": {"notes": notes}},
            )
            data = response.json()
            success = all(id is not None for id in data.get("result", []))
            if success:
                logger.info("Successfully added all cards to Anki")
                return Ok(True)
            else:
                logger.warning("Some cards failed to be added to Anki")
                return Err(CardError("Some cards failed to be added"))
        except requests.exceptions.RequestException as e:
            logger.error(f"Connection error creating Anki cards: {e}")
            return Err(ConnectionError(f"Failed to connect to Anki: {e}"))
        except Exception as e:
            logger.error(f"Error creating Anki cards: {e}")
            return Err(CardError(f"Failed to create cards: {e}"))