from datetime import datetime, timezone
from sqlalchemy import BigInteger, Column, DateTime, Index, String, Text
from sqlalchemy.dialects.postgresql import JSONB
from database.postgres import Base


def _now():
    return datetime.now(timezone.utc)


class MigrationRun(Base):
    """Tracks every migration script execution — what ran, when, row counts, success/failure."""
    __tablename__ = "_migration_runs"

    id          = Column(BigInteger, primary_key=True, autoincrement=True)
    script_name = Column(String(256), nullable=False)
    ran_at      = Column(DateTime(timezone=True), nullable=False, default=_now)
    source_rows = Column(BigInteger, nullable=False, default=0)
    dest_rows   = Column(BigInteger, nullable=False, default=0)
    success     = Column(String(8), nullable=False, default="ok")  # 'ok' | 'error'
    notes       = Column(Text)


class AuditLog(Base):
    """Staff action audit trail — all create/update/delete/command events."""
    __tablename__ = "audit_log"
    __table_args__ = (
        Index("idx_audit_actor",    "actor_id",    "occurred_at"),
        Index("idx_audit_entity",   "entity_type", "entity_id", "occurred_at"),
        Index("idx_audit_action",   "action",      "occurred_at"),
        Index("idx_audit_occurred", "occurred_at"),
    )

    id           = Column(BigInteger, primary_key=True, autoincrement=True)
    occurred_at  = Column(DateTime(timezone=True), nullable=False, default=_now)
    actor_id     = Column(String(128), nullable=False)
    actor_name   = Column(String(255), nullable=False)
    action       = Column(String(64), nullable=False)
    # CREATE | UPDATE | DELETE | COMMAND | PUBLISH | UNPUBLISH |
    # LOGIN | LOGOUT | PERMISSION_CHANGE | STATUS_CHANGE
    entity_type  = Column(String(64), nullable=False)
    # customer | order | device | melody | product | staff | ticket | note | quotation | ...
    entity_id    = Column(String(128), nullable=False)
    entity_label = Column(String(500))   # denormalised human name
    changes      = Column(JSONB)         # {"field": {"old": x, "new": y}} — null for CREATE/DELETE
    meta         = Column(JSONB)         # extra context: ip_address, command_name, etc.
