import os
import random
import logging
import genanki
from datetime import datetime
from typing import List, Tuple, Optional
from .models import GermanWord, UnsplashImage
from .clients.llm import AnthropicClient
from .clients.unsplash import UnsplashClient

logger = logging.getLogger(__name__)

class GermanDeckPackage:
    """Package class to create Anki deck with media files"""
    def __init__(self, deck, media_files):
        self.deck = deck
        self.media_files = media_files

    def write_to_file(self, file):
        """Write deck to a file"""
        package = genanki.Package([self.deck])
        package.media_files = self.media_files
        logger.info("Writing deck with media files: %s", self.media_files)
        package.write_to_file(file)

class CardGenerator:
    def __init__(self, llm_client: AnthropicClient, unsplash_client: UnsplashClient):
        self.llm_client = llm_client
        self.unsplash_client = unsplash_client
        self.model = self._create_model()

    def _create_model(self):
        """Create the Anki note model"""
        return genanki.Model(
            random.randrange(1 << 30, 1 << 31),
            'German Vocabulary Model',
            fields=[
                {'name': 'German_Word'},
                {'name': 'Part_of_Speech'},
                {'name': 'Source'},
                {'name': 'English_Meaning'},
                {'name': 'Article'},
                {'name': 'Plural_Form'},
                {'name': 'Example_Sentence'},
                {'name': 'Sentence_Translation'},
                {'name': 'Usage_Notes'},
                {'name': 'Related_Words'},
                {'name': 'Image'},
                {'name': 'Image_Credit'},
                {'name': 'Tags'}
            ],
            templates=[
                {
                    'name': 'German Vocabulary Card',
                    'qfmt': '''
                        <div style="font-size: 24px;">
                            {{German_Word}} {{tts de_DE:German_Word}}
                        </div>
                        <div style="font-size: 18px;">Part of speech: {{Part_of_Speech}}</div>
                        <div style="font-size: 14px;">Source: {{Source}}</div>
                        {{Image}}
                    ''',
                    'afmt': '''
                        {{FrontSide}}
                        <hr id="answer">
                        <div><b>English meaning:</b> {{English_Meaning}}</div>
                        <div><b>Article:</b> {{Article}}</div>
                        <div><b>Plural Form:</b> {{Plural_Form}}</div>
                        <div>
                            <b>Example:</b> {{Example_Sentence}} {{tts de_DE:Example_Sentence}}
                        </div>
                        <div><b>Translation:</b> {{Sentence_Translation}}</div>
                        <div><b>Usage notes:</b> {{Usage_Notes}}</div>
                        <div><b>Related words:</b> {{Related_Words}}</div>
                        {{#Image_Credit}}<div><small>Photo: {{Image_Credit}}</small></div>{{/Image_Credit}}
                        <div><small>Tags: {{Tags}}</small></div>
                    '''
                }
            ],
            css='''
                .card {
                    font-family: arial;
                    font-size: 16px;
                    text-align: center;
                    color: black;
                    background-color: white;
                }
                img {
                    margin: 20px auto;
                    border-radius: 5px;
                    box-shadow: 0 2px 5px rgba(0,0,0,0.2);
                }
            '''
        )

    def _load_processed_words(self) -> set:
        """Load previously processed words from tracking file"""
        processed_words = set()
        tracking_file = os.path.join("output", "processed_words.txt")
        if os.path.exists(tracking_file):
            with open(tracking_file, 'r', encoding='utf-8') as f:
                processed_words = set(line.strip() for line in f if line.strip())
            logger.info("Found %d previously processed words", len(processed_words))
        return processed_words

    def _add_to_processed_words(self, word: str):
        """Add a word to the tracking file"""
        tracking_file = os.path.join("output", "processed_words.txt")
        os.makedirs("output", exist_ok=True)
        with open(tracking_file, 'a', encoding='utf-8') as f:
            f.write(f"{word}\n")
        logger.debug("Added %s to processed words", word)

    def create_deck(self, word_list: List[Tuple[str, str]], deck_name: str = "German Vocabulary") -> Tuple[genanki.Deck, List[str]]:
        """Create an Anki deck from a list of words"""
        deck_id = random.randrange(1 << 30, 1 << 31)
        deck = genanki.Deck(deck_id, deck_name)
        media_files = []
        
        # Load previously processed words
        processed_words = self._load_processed_words()

        for word, source in word_list:
            # Skip if word has been processed before
            if word in processed_words:
                logger.info("Skipping %s - already exists in previous deck", word)
                continue
            try:
                card_info_dict = self.llm_client.get_card_info(word, source)
                card_info = GermanWord(**card_info_dict)

                image_filename = f"{word.lower().replace(' ', '_')}.jpg"
                
                # Create output directory if it doesn't exist
                output_dir = "output"
                os.makedirs(output_dir, exist_ok=True)

                media_dir = "media"
                os.makedirs(media_dir, exist_ok=True)
                
                # Save image directly to media directory
                image_path = os.path.join(media_dir, image_filename)
                image = self.unsplash_client.get_image(
                    card_info.image_search_term,
                    image_path
                )

                if image and image.local_path and os.path.exists(image.local_path):
                    # Use the full path for the media file
                    media_files.append(image.local_path)
                    logger.info("Added image: %s", image.local_path)
                else:
                    image_path = ""
                    logger.warning("No image for: %s", word)

                # Create note
                note = genanki.Note(
                    model=self.model,
                    fields=[
                        card_info.german_word,
                        card_info.part_of_speech,
                        source,
                        card_info.english_meaning,
                        card_info.article or "",
                        card_info.plural_form,
                        card_info.example_sentence,
                        card_info.sentence_translation,
                        card_info.usage_notes,
                        card_info.related_words,
                        f'<img src="{os.path.basename(image.local_path) if image and image.local_path else ""}" />',
                        image.photographer if image else "",
                        ' '.join(card_info.tags)
                    ]
                )
                deck.add_note(note)
                # Track the word after successfully creating the note
                self._add_to_processed_words(word)
                logger.info("Added card for: %s", word)

            except Exception as e:
                logger.error("Error creating card for %s: %s", word, str(e))

        return deck, media_files
