"""ORM 模型。

存储要点：
- users.password_hash: bcrypt 哈希，不存明文。
- api_keys.key_hash: API Key 明文只给用户看一次，库内存 SHA-256 哈希，
  索引建在 key_hash 上以便 O(1) 校验。
"""
import datetime as dt
import hashlib

from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Boolean
from sqlalchemy.orm import relationship

from .database import Base


def utcnow():
    return dt.datetime.utcnow()


class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True)
    username = Column(String(64), unique=True, index=True, nullable=False)
    password_hash = Column(String(255), nullable=False)
    created_at = Column(DateTime, default=utcnow)

    api_keys = relationship(
        "ApiKey", back_populates="user", cascade="all, delete-orphan"
    )


class ApiKey(Base):
    __tablename__ = "api_keys"

    id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True)
    # 存 key 的 SHA-256 哈希，唯一索引支持快速校验
    key_hash = Column(String(64), unique=True, index=True, nullable=False)
    # key 的前缀，用于在列表里展示，方便用户辨认（无安全价值）
    key_prefix = Column(String(16), nullable=False)
    name = Column(String(128), default="default")
    created_at = Column(DateTime, default=utcnow)
    last_used_at = Column(DateTime, nullable=True)
    revoked = Column(Boolean, default=False, nullable=False)

    user = relationship("User", back_populates="api_keys")

    @staticmethod
    def hash_key(raw: str) -> str:
        """对 API Key 明文做 SHA-256。"""
        return hashlib.sha256(raw.encode("utf-8")).hexdigest()
