"""Database configuration and models for Claude Code Monitor."""

from sqlalchemy import (
    create_engine,
    Column,
    Integer,
    String,
    Float,
    Boolean,
    DateTime,
    Index,
    CheckConstraint,
)
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql import func
import os

# Database URL
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./data/claude_monitor.db")

# Create engine with WAL mode for better concurrency
engine = create_engine(
    DATABASE_URL,
    connect_args={"check_same_thread": False} if "sqlite" in DATABASE_URL else {},
    echo=False,
)

# Session factory
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# Base class for models
Base = declarative_base()


class Event(Base):
    """Event model for storing Claude Code events."""

    __tablename__ = "events"

    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    session_id = Column(String, nullable=False, index=True)
    event_type = Column(String, nullable=False, index=True)  # PreToolUse, PostToolUse, etc.
    tool_name = Column(String, nullable=True, index=True)  # Bash, Read, Write, etc.
    tool_input = Column(String, nullable=True)  # JSON string
    tool_output = Column(String, nullable=True)  # Tool response
    success = Column(Boolean, nullable=True)  # Success/failure (NULL for PreToolUse)
    description = Column(String, nullable=True)  # Human-readable description
    timestamp = Column(Float, nullable=False, index=True)  # Unix timestamp
    created_at = Column(DateTime, server_default=func.now())

    __table_args__ = (
        Index("idx_event_type_timestamp", "event_type", "timestamp"),
        Index("idx_session_timestamp", "session_id", "timestamp"),
    )


class Session(Base):
    """Session model for tracking Claude Code sessions."""

    __tablename__ = "sessions"

    session_id = Column(String, primary_key=True)
    started_at = Column(Float, nullable=False, index=True)
    ended_at = Column(Float, nullable=True)
    event_count = Column(Integer, default=0)
    created_at = Column(DateTime, server_default=func.now())


class Statistics(Base):
    """Statistics model for cached aggregations (single-row table)."""

    __tablename__ = "statistics"

    id = Column(Integer, primary_key=True)
    total_events = Column(Integer, default=0)
    total_tools_used = Column(Integer, default=0)
    total_agents = Column(Integer, default=0)
    total_sessions = Column(Integer, default=0)
    last_updated = Column(Float, nullable=False)

    __table_args__ = (CheckConstraint("id = 1", name="single_row"),)


class ToolUsage(Base):
    """Tool usage model for tracking unique tools."""

    __tablename__ = "tool_usage"

    tool_name = Column(String, primary_key=True)
    usage_count = Column(Integer, default=1)
    first_used = Column(Float, nullable=False)
    last_used = Column(Float, nullable=False, index=True)


def init_db():
    """Initialize database: create tables and enable WAL mode."""
    # Create all tables
    Base.metadata.create_all(bind=engine)

    # Enable WAL mode for SQLite
    if "sqlite" in DATABASE_URL:
        with engine.connect() as conn:
            conn.execute("PRAGMA journal_mode=WAL")
            conn.commit()

    # Initialize statistics table with single row
    db = SessionLocal()
    try:
        stats = db.query(Statistics).first()
        if not stats:
            stats = Statistics(
                id=1,
                total_events=0,
                total_tools_used=0,
                total_agents=0,
                total_sessions=0,
                last_updated=0.0,
            )
            db.add(stats)
            db.commit()
    finally:
        db.close()


def get_db():
    """Dependency for getting database session."""
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()
