import sqlite3
from dataclasses import dataclass
import hashlib
from typing import Optional

@dataclass
class AuditModel:
    id: Optional[int] = None
    user_id: Optional[int] = None
    action: Optional[str] = None
    endpoint: Optional[str] = None
    created_at: Optional[str] = None
    status: Optional[str] = None


class Audit:
    def __init__(self, db_path="instance/app_database.db"):
        self.db_path = db_path
        self._create_audit_table()

    def _create_audit_table(self):
        with sqlite3.connect(self.db_path) as conn:
            cursor = conn.cursor()
            cursor.execute(
                """
                CREATE TABLE IF NOT EXISTS audit (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    user_id INTEGER NOT NULL,
                    action TEXT,
                    endpoint TEXT,
                    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                    status TEXT
                );
                """
            )
            conn.commit()

    def new_entry(self, entry:AuditModel):
        """Create a new entry."""
        try:
            with sqlite3.connect(self.db_path) as conn:
                cursor = conn.cursor()
                cursor.execute(
                    """
                    INSERT INTO audit (user_id, action, endpoint, status)
                    VALUES (?, ?, ?, ?)
                    """,
                    (entry.user_id, entry.action, entry.endpoint, entry.status),
                )
                conn.commit()
                return cursor.lastrowid
        except sqlite3.IntegrityError:
            return None
        
    def get_all_entries(self):
        with sqlite3.connect(self.db_path) as conn:
            cursor = conn.cursor()
            cursor.execute("SELECT * FROM audit")
            rows = cursor.fetchall()

            return [
                AuditModel(
                    id = row[0],
                    user_id =  row[1],
                    action = row[2],
                    endpoint = row[3],
                    created_at = row[4],
                    status = row[5]
                )
                for row in rows
            ]
        
    def get_entries_by_user_id(self, user_id):
        with sqlite3.connect(self.db_path) as conn:
            cursor = conn.cursor()
            cursor.execute("SELECT * FROM audit WHERE user_id = ?", (user_id, ))
            rows = cursor.fetchall()

            return [
                AuditModel(
                    id = row[0],
                    user_id =  row[1],
                    action = row[2],
                    endpoint = row[3],
                    created_at = row[4],
                    status = row[5]
                )
                for row in rows
            ]
        
    def delete_entries_older_than(self, date_string):
        """
        Deletes logs older than the provided date.
        Expected date_string format: 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS'
        """
        try:
            with sqlite3.connect(self.db_path) as conn:
                cursor = conn.cursor()
                # SQLite allows direct string comparison for ISO 8601 dates
                cursor.execute(
                    "DELETE FROM audit WHERE created_at < ?",
                    (date_string,)
                )
                conn.commit()
                return cursor.rowcount  # Returns the number of deleted rows
        except sqlite3.Error as e:
            print(f"An error occurred: {e}")
            return 0
