import sqlite3
import os
from pathlib import Path
from datetime import datetime, timedelta


def get_db_path():
    """Get the absolute path to the database file in ~/.loggerheads_logs/"""
    log_dir = Path.home() / ".loggerheads_logs"
    log_dir.mkdir(exist_ok=True)
    return str(log_dir / "activity_log.db")


def init_db(db_path=None):
    if db_path is None:
        db_path = get_db_path()
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    # Create logs table
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS logs (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            window_name TEXT,
            timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
        )
    """)

    # Create screenshots table
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS screenshots (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            file_path TEXT NOT NULL,
            timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
            extracted_text TEXT,
            log_id INTEGER,
            FOREIGN KEY (log_id) REFERENCES logs(id)
        )
    """)

    # Create liveness checks table
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS liveness_checks (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
            face_detected BOOLEAN NOT NULL,
            confidence REAL NOT NULL,
            face_count INTEGER NOT NULL,
            error TEXT
        )
    """)

    conn.commit()
    conn.close()


def save_logs(logs):
    db_path = get_db_path()
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    cursor.executemany("INSERT INTO logs (window_name) VALUES (?)", [(log,) for log in logs])
    conn.commit()
    conn.close()


def save_screenshot(file_path, extracted_text="", log_id=None, timestamp=None):
    """
    Save screenshot metadata to database.

    Args:
        file_path (str): Path to the screenshot file
        extracted_text (str): OCR-extracted text from the screenshot
        log_id (int, optional): ID of related activity log entry
        timestamp (str, optional): Custom timestamp (ISO format) for demo mode
    """
    db_path = get_db_path()
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    
    if timestamp:
        # Custom timestamp (for demo mode)
        cursor.execute(
            "INSERT INTO screenshots (file_path, extracted_text, log_id, timestamp) VALUES (?, ?, ?, ?)",
            (file_path, extracted_text, log_id, timestamp)
        )
    else:
        # Auto timestamp (normal operation)
        cursor.execute(
            "INSERT INTO screenshots (file_path, extracted_text, log_id) VALUES (?, ?, ?)",
            (file_path, extracted_text, log_id)
        )
    
    conn.commit()
    conn.close()


def get_screenshots(limit=None, today_only=False, db_path=None):
    """
    Retrieve screenshots from database.

    Args:
        limit (int, optional): Maximum number of screenshots to retrieve
        today_only (bool, optional): If True, only return today's screenshots
        db_path (str, optional): Custom database path (defaults to standard path)

    Returns:
        list: List of tuples containing screenshot data
    """
    if db_path is None:
        db_path = get_db_path()
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    if today_only:
        # Filter to today's screenshots only
        if limit:
            cursor.execute(
                "SELECT id, file_path, timestamp, extracted_text FROM screenshots "
                "WHERE DATE(timestamp) = DATE('now') "
                "ORDER BY timestamp DESC LIMIT ?",
                (limit,)
            )
        else:
            cursor.execute(
                "SELECT id, file_path, timestamp, extracted_text FROM screenshots "
                "WHERE DATE(timestamp) = DATE('now') "
                "ORDER BY timestamp DESC"
            )
    else:
        # All screenshots (original behavior)
        if limit:
            cursor.execute(
                "SELECT id, file_path, timestamp, extracted_text FROM screenshots ORDER BY timestamp DESC LIMIT ?",
                (limit,)
            )
        else:
            cursor.execute(
                "SELECT id, file_path, timestamp, extracted_text FROM screenshots ORDER BY timestamp DESC"
            )

    results = cursor.fetchall()
    conn.close()
    return results


def calculate_hours_worked_today(db_path=None):
    """
    Calculate total hours worked today based on screenshot timestamps.
    Assumes screenshots are taken at regular intervals during active work.

    Returns:
        int: Number of hours worked (rounded)
    """
    if db_path is None:
        db_path = get_db_path()
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    # Get all screenshots from today using DATE comparison (works with any timestamp format)
    cursor.execute("""
        SELECT timestamp FROM screenshots
        WHERE DATE(timestamp) = DATE('now')
        ORDER BY timestamp ASC
    """)

    timestamps = cursor.fetchall()
    conn.close()

    if not timestamps or len(timestamps) < 2:
        return 0

    # Parse timestamps
    times = [datetime.fromisoformat(ts[0]) for ts in timestamps]

    # FIXED: Calculate based on screenshot frequency, not time span
    # Screenshots are taken every 10 seconds during active work
    # Count gaps between screenshots to determine active vs idle periods

    active_seconds = 0
    MAX_GAP_SECONDS = 60  # If gap > 60 seconds, consider it idle time (missed screenshots)

    for i in range(len(times) - 1):
        gap_seconds = (times[i+1] - times[i]).total_seconds()

        if gap_seconds <= MAX_GAP_SECONDS:
            # Active period - count the gap as work time
            active_seconds += gap_seconds
        # else: Idle period (break, lunch, stepped away) - don't count

    # Convert to hours
    hours_worked = active_seconds / 3600

    # Return actual hours (round to 1 decimal place for readability)
    return round(hours_worked, 1)


def save_liveness_check(face_detected, confidence, face_count, error=None, timestamp=None):
    """
    Save liveness check result to database.

    Args:
        face_detected (bool): Whether a face was detected
        confidence (float): Detection confidence (0.0-1.0)
        face_count (int): Number of faces detected
        error (str, optional): Error message if check failed
        timestamp (str, optional): Custom timestamp (ISO format)
    """
    db_path = get_db_path()
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    if timestamp:
        cursor.execute(
            "INSERT INTO liveness_checks (face_detected, confidence, face_count, error, timestamp) "
            "VALUES (?, ?, ?, ?, ?)",
            (face_detected, confidence, face_count, error, timestamp)
        )
    else:
        cursor.execute(
            "INSERT INTO liveness_checks (face_detected, confidence, face_count, error) "
            "VALUES (?, ?, ?, ?)",
            (face_detected, confidence, face_count, error)
        )

    conn.commit()
    conn.close()


def get_liveness_checks_today(db_path=None):
    """
    Get all liveness checks from today.

    Args:
        db_path (str, optional): Custom database path

    Returns:
        list: List of tuples with liveness check data
    """
    if db_path is None:
        db_path = get_db_path()

    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    cursor.execute("""
        SELECT timestamp, face_detected, confidence, face_count, error
        FROM liveness_checks
        WHERE DATE(timestamp) = DATE('now')
        ORDER BY timestamp ASC
    """)

    results = cursor.fetchall()
    conn.close()
    return results
