# database.py
import sqlite3
import os

DB_NAME = "spanish_trainer.db"

def get_connection():
    """Returns a connection to the SQLite database with row factory enabled."""
    conn = sqlite3.connect(DB_NAME)
    conn.row_factory = sqlite3.Row
    return conn

def ensure_database_populated():
    """
    Creates empty tables using the unified schema if running 
    in a fresh environment without a database file.
    """
    conn = get_connection()
    cursor = conn.cursor()
    try:
        # 1. Unified translations table with dedicated anki_notes and gender tracks
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS translations (
                translation_id INTEGER PRIMARY KEY AUTOINCREMENT,
                es_text TEXT NOT NULL,
                en_text TEXT NOT NULL,
                source_context TEXT,
                tags TEXT,
                notes TEXT,
                anki_notes TEXT DEFAULT '',
                gender TEXT DEFAULT 'Female'
            );
        """)
        
        # 2. Key-value configuration table
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS settings (
                key TEXT PRIMARY KEY,
                value TEXT
            );
        """)
        conn.commit()
    finally:
        conn.close()

# ==========================================
# SETTINGS CRUD FUNCTIONS
# ==========================================

def load_all_settings():
    """Fetches all system configuration properties into a flat Python dictionary."""
    conn = get_connection()
    cursor = conn.cursor()
    settings_dict = {}
    try:
        cursor.execute("SELECT settings.key, settings.value FROM settings;")
        for row in cursor.fetchall():
            settings_dict[row["key"]] = row["value"]
    finally:
        conn.close()
    return settings_dict

def save_setting_to_db(key, value):
    """Inserts or replaces an application configuration entry."""
    conn = get_connection()
    cursor = conn.cursor()
    try:
        cursor.execute("""
            INSERT OR REPLACE INTO settings (key, value)
            VALUES (?, ?);
        """, (key, value))
        conn.commit()
    finally:
        conn.close()

# ==========================================
# TRANSLATIONS CRUD FUNCTIONS
# ==========================================

def get_all_translations_explicit():
    """
    Retrieves all records using completely explicit, 
    table-qualified column declarations for the engines.
    """
    conn = get_connection()
    cursor = conn.cursor()
    try:
        cursor.execute("""
            SELECT 
                translations.translation_id,
                translations.es_text,
                translations.en_text,
                translations.source_context,
                translations.tags,
                translations.notes,
                translations.anki_notes,
                translations.gender
            FROM translations
            ORDER BY translations.translation_id ASC;
        """)
        return [dict(row) for row in cursor.fetchall()]
    finally:
        conn.close()

def get_translation_by_id(translation_id):
    """Loads a single unified record row for specific inspection or editing."""
    conn = get_connection()
    cursor = conn.cursor()
    try:
        cursor.execute("""
            SELECT 
                translations.translation_id,
                translations.es_text,
                translations.en_text,
                translations.source_context,
                translations.tags,
                translations.notes,
                translations.anki_notes,
                translations.gender
            FROM translations
            WHERE translations.translation_id = ?;
        """, (translation_id,))
        row = cursor.fetchone()
        return dict(row) if row else None
    finally:
        conn.close()

def update_translation_record(translation_id, es_text, en_text, source_context, tags, notes, gender, anki_notes):
    """Saves sandbox interface edits directly back down into the table using named arguments."""
    conn = get_connection()
    cursor = conn.cursor()
    try:
        # The SQL uses :key syntax instead of ?
        cursor.execute("""
            UPDATE translations
            SET 
                es_text = :es,
                en_text = :en,
                source_context = :ctx,
                tags = :tags,
                notes = :notes,
                gender = :gender,
                anki_notes = :anki
            WHERE translation_id = :id;
        """, {
            # The order inside this dictionary does not matter at all!
            "id": translation_id,
            "es": es_text,
            "en": en_text,
            "ctx": source_context,
            "tags": tags,
            "notes": notes,
            "gender": gender,
            "anki": anki_notes
        })
        conn.commit()
    finally:
        conn.close()

def delete_translation_record(translation_id):
    """Permanently drops a phrase card row from the data index."""
    conn = get_connection()
    cursor = conn.cursor()
    try:
        cursor.execute("""
            DELETE FROM translations
            WHERE translations.translation_id = ?;
        """, (translation_id,))
        conn.commit()
    finally:
        conn.close()

def insert_translation_record(es_text, en_text, source_context, tags, notes, gender, anki_notes):
    """Inserts a new record using named arguments so positional order doesn't matter."""
    conn = get_connection()  # Corrected from get_db_connection
    cursor = conn.cursor()
    try:
        cursor.execute("""
            INSERT INTO translations (es_text, en_text, source_context, tags, notes, gender, anki_notes)
            VALUES (:es, :en, :ctx, :tags, :notes, :gender, :anki);
        """, {
            # SQLite maps these keys directly to the tokens above by name
            "en": en_text,
            "es": es_text,
            "ctx": source_context,
            "tags": tags,
            "notes": notes,
            "anki": anki_notes,
            "gender": gender
        })
        conn.commit()
    finally:
        conn.close()

