#!/usr/bin/env python3
"""
Script pour sélectionner les cartes quotidiennes du système Anki Tingting.

Usage:
    python get_daily_cards.py [--num-cards N] [--json]

Options:
    --num-cards N  : Nombre de cartes à sélectionner (défaut: 3)
    --json         : Output en JSON (défaut: texte lisible)
"""

import sys
import os
import re
import json
import argparse
from datetime import datetime, timedelta
from pathlib import Path


# Chemins relatifs au script
SCRIPT_DIR = Path(__file__).parent
BASE_DIR = SCRIPT_DIR.parent
CARD_DB_PATH = BASE_DIR / "card_database.md"
CARDS_DIR = BASE_DIR / "cards"


def parse_date(date_str):
    """Parse une date au format DD/MM/YYYY ou 'Never'."""
    if date_str == "Never" or date_str == "N/A":
        return None
    try:
        return datetime.strptime(date_str, "%d/%m/%Y")
    except ValueError:
        return None


def parse_card_database():
    """Parse le fichier card_database.md et retourne la liste des cartes."""
    if not CARD_DB_PATH.exists():
        print(f"❌ ERREUR: Fichier {CARD_DB_PATH} introuvable", file=sys.stderr)
        sys.exit(1)

    with open(CARD_DB_PATH, 'r', encoding='utf-8') as f:
        content = f.read()

    # Trouver la table markdown
    table_pattern = r'\| ID \| Card \| Difficulty.*?\n\|---.*?\n((?:\|.*?\n)+)'
    match = re.search(table_pattern, content, re.DOTALL)

    if not match:
        print("❌ ERREUR: Impossible de trouver la table dans card_database.md", file=sys.stderr)
        print("ℹ️  Le fichier doit contenir une table markdown avec colonnes:", file=sys.stderr)
        print("   | ID | Card | Difficulty | Frequency | Last Review | Success Rate | Failures | Critical |", file=sys.stderr)
        sys.exit(1)

    table_rows = match.group(1).strip().split('\n')
    print(f"ℹ️  INFO: {len(table_rows)} lignes de table trouvées", file=sys.stderr)

    cards = []
    for i, row in enumerate(table_rows, 1):
        # Parse chaque ligne de la table
        cols = [col.strip() for col in row.split('|')[1:-1]]  # Ignore les | de début/fin

        if len(cols) < 8:
            print(f"⚠️  WARNING: Ligne {i} ignorée (seulement {len(cols)} colonnes au lieu de 8)", file=sys.stderr)
            continue

        card_id, card_link, difficulty, frequency, last_review, success_rate, times_failed, critical = cols

        # Extraire le nom du fichier depuis le lien markdown [filename](cards/filename.md)
        filename_match = re.search(r'\[(.*?\.md)\]', card_link)
        if not filename_match:
            print(f"⚠️  WARNING: Impossible d'extraire le filename de: {card_link}", file=sys.stderr)
            continue

        card_file = filename_match.group(1)

        cards.append({
            'id': card_id,
            'file': card_file,
            'difficulty': difficulty,
            'frequency': frequency,
            'last_review': parse_date(last_review),
            'last_review_str': last_review,
            'success_rate': success_rate,
            'times_failed': int(times_failed) if times_failed.isdigit() else 0,
            'critical': critical == '⚠️'
        })

    print(f"✅ SUCCESS: {len(cards)} cartes chargées depuis la table", file=sys.stderr)
    return cards




def load_card_content(card_file):
    """Charge le contenu d'une carte depuis son fichier."""
    card_path = CARDS_DIR / card_file

    if not card_path.exists():
        print(f"⚠️  WARNING: Fichier {card_file} introuvable dans {CARDS_DIR}", file=sys.stderr)
        return {
            'question': f"[FICHIER MANQUANT: {card_file}]",
            'answer': "Le fichier de cette carte est introuvable",
            'notes': ""
        }

    try:
        with open(card_path, 'r', encoding='utf-8') as f:
            content = f.read()

        # Extract question
        question_match = re.search(r'## Question\s*\n\s*\n(.*?)\n\s*\n---', content, re.DOTALL)
        question = question_match.group(1).strip() if question_match else "Question non trouvée"

        # Extract answer
        answer_match = re.search(r'## Answer\s*\n\s*\n(.*?)\n\s*\n---', content, re.DOTALL)
        answer = answer_match.group(1).strip() if answer_match else "Réponse non trouvée"

        # Extract notes
        notes_match = re.search(r'## Notes\s*\n\s*\n(.*?)\n\s*\n---', content, re.DOTALL)
        notes = notes_match.group(1).strip() if notes_match else ""

        return {
            'question': question,
            'answer': answer,
            'notes': notes
        }

    except Exception as e:
        print(f"⚠️  WARNING: Erreur lors du chargement de {card_file}: {e}", file=sys.stderr)
        return {
            'question': f"[ERREUR: {card_file}]",
            'answer': f"Erreur lors du chargement: {e}",
            'notes': ""
        }


def calculate_priority_score(card, today):
    """Calcule un score de priorité pour une carte."""
    score = 0

    # CRITICAL cards = haute priorité
    if card['critical']:
        score += 100

    # Times failed = haute priorité
    score += card['times_failed'] * 50

    # Difficulté
    difficulty_scores = {'Hard': 30, 'Medium': 20, 'Easy': 10}
    score += difficulty_scores.get(card['difficulty'], 0)

    # Temps depuis dernière review
    if card['last_review'] is None:
        score += 200  # Jamais révisée = très haute priorité
    else:
        days_since = (today - card['last_review']).days

        # Calculer le nombre de jours attendus selon frequency
        freq_days = {
            'Daily': 1,
            'Every 2-3 days': 2,
            'Every 3-4 days': 3,
            'Every 2 weeks': 14,
            'Monthly': 30,
            'Every conflict': 999  # Pas basé sur le temps
        }

        expected_days = freq_days.get(card['frequency'], 7)

        if card['frequency'] == 'Every conflict':
            # Cartes de conflit : priorité basse sauf si jamais révisées
            score += 5
        elif days_since >= expected_days:
            # En retard sur la review
            score += 80 + (days_since - expected_days) * 10
        else:
            # Pas encore le moment
            score += 5

    # Success rate (si disponible)
    if card['success_rate'] not in ['N/A', 'Never']:
        try:
            rate = int(card['success_rate'].replace('%', ''))
            if rate < 70:
                score += 40
        except ValueError:
            pass

    return score


def select_daily_cards(num_cards=3):
    """Sélectionne les cartes pour la session quotidienne."""
    cards = parse_card_database()
    today = datetime.now()

    # Calculer le score de priorité pour chaque carte
    for card in cards:
        card['priority_score'] = calculate_priority_score(card, today)

    # Trier par priorité décroissante
    cards.sort(key=lambda c: c['priority_score'], reverse=True)

    # Sélectionner les N premières cartes
    selected = cards[:num_cards]

    # Charger le contenu de chaque carte depuis les fichiers individuels
    for card in selected:
        content = load_card_content(card['file'])
        card.update(content)

    return selected


def format_output_text(cards):
    """Formate l'output en texte lisible."""
    output = []
    output.append("=" * 60)
    output.append(f"📚 CARTES SÉLECTIONNÉES - {datetime.now().strftime('%d/%m/%Y')}")
    output.append("=" * 60)
    output.append("")

    for i, card in enumerate(cards, 1):
        output.append(f"🎯 CARTE {i}/3")
        output.append(f"ID: {card['id']}")
        output.append(f"Fichier: {card['file']}")
        output.append(f"Difficulté: {card['difficulty']} | Critique: {'⚠️ OUI' if card['critical'] else 'Non'}")
        output.append(f"Dernière review: {card['last_review_str']}")
        output.append(f"Score priorité: {card['priority_score']}")
        output.append("")
        output.append(f"QUESTION:")
        output.append(card['question'])
        output.append("")
        output.append(f"RÉPONSE ATTENDUE:")
        output.append(card['answer'])
        output.append("")
        if card['notes']:
            output.append(f"NOTES:")
            output.append(card['notes'])
            output.append("")
        output.append("-" * 60)
        output.append("")

    return "\n".join(output)


def format_output_json(cards):
    """Formate l'output en JSON."""
    return json.dumps({
        'date': datetime.now().strftime('%d/%m/%Y'),
        'cards': [
            {
                'id': card['id'],
                'file': card['file'],
                'difficulty': card['difficulty'],
                'critical': card['critical'],
                'last_review': card['last_review_str'],
                'priority_score': card['priority_score'],
                'question': card['question'],
                'answer': card['answer'],
                'notes': card['notes']
            }
            for card in cards
        ]
    }, indent=2, ensure_ascii=False)


def main():
    parser = argparse.ArgumentParser(description='Sélectionne les cartes quotidiennes')
    parser.add_argument('--num-cards', type=int, default=3, help='Nombre de cartes à sélectionner')
    parser.add_argument('--json', action='store_true', help='Output en JSON')

    args = parser.parse_args()

    try:
        cards = select_daily_cards(args.num_cards)

        if not cards:
            print("❌ ERREUR: Aucune carte n'a pu être chargée", file=sys.stderr)
            sys.exit(1)

        if args.json:
            print(format_output_json(cards))
        else:
            print(format_output_text(cards))

    except KeyboardInterrupt:
        print("\n⚠️  Interrompu par l'utilisateur", file=sys.stderr)
        sys.exit(130)
    except Exception as e:
        print(f"❌ ERREUR FATALE: {e}", file=sys.stderr)
        import traceback
        traceback.print_exc(file=sys.stderr)
        sys.exit(1)


if __name__ == '__main__':
    main()
