"""
spidercrypt.db
~~~~~~~~~~~~~~
SQLite audit log — SQLAlchemy models and session helpers.
"""

import json
from datetime import datetime
from pathlib import Path
from typing import List

from sqlalchemy import create_engine, Column, Integer, String, Text, DateTime
from sqlalchemy.orm import declarative_base, sessionmaker, Session

Base = declarative_base()

_engine  = None
_Session = None


class AuditLog(Base):
    """One row per scan result saved to the database."""
    __tablename__ = "audit_logs"

    id        = Column(Integer, primary_key=True)
    filename  = Column(String(255))
    timestamp = Column(DateTime, default=datetime.utcnow)
    report    = Column(Text)

    def as_dict(self):
        return {
            "id":        self.id,
            "filename":  self.filename,
            "timestamp": str(self.timestamp),
            "report":    json.loads(self.report) if self.report else {},
        }


def init_db(db_path: str = "spidercrypt.db") -> None:
    """
    Initialise (or reuse) the SQLite database at *db_path*.

    Called automatically the first time :func:`get_session` is used.
    """
    global _engine, _Session
    _engine  = create_engine(f"sqlite:///{db_path}")
    Base.metadata.create_all(_engine)
    _Session = sessionmaker(bind=_engine)


def get_session(db_path: str = "spidercrypt.db") -> Session:
    """Return a new SQLAlchemy session, initialising the DB if needed."""
    if _Session is None:
        init_db(db_path)
    return _Session()


def save_report(filename: str, report: dict, db_path: str = "spidercrypt.db") -> None:
    """Persist *report* for *filename* to the audit log."""
    session = get_session(db_path)
    entry   = AuditLog(filename=filename, report=json.dumps(report, ensure_ascii=False))
    session.add(entry)
    session.commit()
    session.close()


def get_history(db_path: str = "spidercrypt.db") -> List[dict]:
    """Return all audit log entries as a list of dicts."""
    session = get_session(db_path)
    logs    = session.query(AuditLog).order_by(AuditLog.timestamp.desc()).all()
    result  = [log.as_dict() for log in logs]
    session.close()
    return result