"""Attendance & Access Control aggregates — Phase 9.5."""
from __future__ import annotations

import uuid
from datetime import datetime

from sqlalchemy import DateTime, Index, String, Text
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.types import JSON

from app.core.database import Base
from app.models.base import (
    ActorAuditMixin,
    SoftDeleteMixin,
    TenantMixin,
    TimestampMixin,
    UUIDPrimaryKeyMixin,
)
from app.models.types import AccessResult, AttendanceKind, AttendanceStatus, GUID


class AttendanceRecord(
    Base,
    UUIDPrimaryKeyMixin,
    TenantMixin,
    TimestampMixin,
    SoftDeleteMixin,
    ActorAuditMixin,
):
    __tablename__ = "attendance_records"

    sports_center_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    branch_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    member_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    membership_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    session_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    attendance_kind: Mapped[AttendanceKind] = mapped_column(nullable=False)
    status: Mapped[AttendanceStatus] = mapped_column(nullable=False)
    recorded_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
    device_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    gateway_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    card_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    pass_code: Mapped[str | None] = mapped_column(String(100), nullable=True)
    notes: Mapped[str | None] = mapped_column(Text, nullable=True)
    metadata_json: Mapped[dict | None] = mapped_column(JSON, nullable=True)

    __table_args__ = (
        Index("ix_attendance_records_member", "tenant_id", "member_id"),
        Index("ix_attendance_records_recorded", "tenant_id", "recorded_at"),
        Index("ix_attendance_records_session", "tenant_id", "session_id"),
        Index("ix_attendance_records_tenant_deleted", "tenant_id", "is_deleted"),
    )


class AccessLog(
    Base,
    UUIDPrimaryKeyMixin,
    TenantMixin,
    TimestampMixin,
    SoftDeleteMixin,
    ActorAuditMixin,
):
    __tablename__ = "access_logs"

    sports_center_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    branch_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    member_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    membership_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    device_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    gateway_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    access_result: Mapped[AccessResult] = mapped_column(nullable=False)
    access_method: Mapped[str | None] = mapped_column(String(50), nullable=True)
    credential_ref: Mapped[str | None] = mapped_column(String(255), nullable=True)
    recorded_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
    denial_reason: Mapped[str | None] = mapped_column(String(255), nullable=True)
    metadata_json: Mapped[dict | None] = mapped_column(JSON, nullable=True)

    __table_args__ = (
        Index("ix_access_logs_member", "tenant_id", "member_id"),
        Index("ix_access_logs_recorded", "tenant_id", "recorded_at"),
        Index("ix_access_logs_gateway", "tenant_id", "gateway_id"),
        Index("ix_access_logs_tenant_deleted", "tenant_id", "is_deleted"),
    )
