"""
LINE 綁定碼資料表(階段 6b)。

用途:讓 Cooper 網頁版的 user 跟 LINE 上的 line_user_id 綁定起來。

流程:
  1. user 在網頁版按「產生 LINE 綁定碼」 → 後端 INSERT 一筆 LineBindingCode (6 位數,TTL 10 分鐘)
  2. user 在 LINE 對 Cooper 說「綁定 482593」
  3. line_bridge 攔到關鍵字,redeem 這個 code:
     - 把 LINE shadow user 的 line_user_id 搬到網頁 user
     - shadow user 軟刪
     - 此 code 標記 used_at,失效

設計:
  - code 全表唯一(避免兩個人同時拿到一樣的數字),unique index
  - used_at IS NULL 才有效,避免重放
  - expires_at 過期 → redeem 拒絕
"""

from datetime import datetime
from uuid import UUID, uuid4

from sqlalchemy import DateTime, ForeignKey, String, Uuid
from sqlalchemy.orm import Mapped, mapped_column

from app.database import Base
from app.models.user import TimestampMixin


class LineBindingCode(Base, TimestampMixin):
    """LINE ↔ Cooper 帳號綁定一次性碼。"""

    __tablename__ = "line_binding_codes"

    id: Mapped[UUID] = mapped_column(Uuid(as_uuid=True), primary_key=True, default=uuid4)

    # 6 位數字字串(避免 leading zero 被當成 int 截斷,用 String)
    code: Mapped[str] = mapped_column(String(6), unique=True, nullable=False, index=True)

    # 是哪個網頁使用者產的(redeem 完會把 LINE 綁到他身上)
    user_id: Mapped[UUID] = mapped_column(
        Uuid(as_uuid=True),
        ForeignKey("users.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )

    expires_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        nullable=False,
    )
    # 已被 redeem 的 code,used_at 不為 NULL
    used_at: Mapped[datetime | None] = mapped_column(
        DateTime(timezone=True),
        nullable=True,
    )

    def __repr__(self) -> str:
        return f"<LineBindingCode {self.code} user={self.user_id} used={self.used_at}>"
