"""
用户模型
========

采用"手机号 + JWT"的认证方案，支持单设备登录约束。
"""

import enum
from datetime import datetime

from sqlalchemy import DateTime, String, Text
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped, mapped_column

from app.models.base import BaseModel


class UserStatus(str, enum.Enum):
    """用户状态"""

    ACTIVE = "active"  # 正常
    SUSPENDED = "suspended"  # 封禁（可解封）
    PENDING_DELETE = "pending_delete"  # 申请注销，30 天后自动删除
    DELETED = "deleted"  # 已删除（逻辑删除，数据保留 90 天）


class User(BaseModel):
    """用户表"""

    __tablename__ = "mjk_users"

    # ========== 认证标识 ==========
    mobile: Mapped[str] = mapped_column(
        String(20),
        unique=True,
        nullable=False,
        comment="手机号，登录账号",
    )

    # ========== 安全相关 ==========
    password_hash: Mapped[str | None] = mapped_column(
        String(255),
        nullable=True,
        comment="密码哈希（bcrypt），预留字段",
    )

    status: Mapped[str] = mapped_column(
        String(20),
        default=UserStatus.ACTIVE.value,
        nullable=False,
        comment="账号状态",
    )

    # ========== 用户画像 ==========
    nickname: Mapped[str | None] = mapped_column(
        String(64),
        nullable=True,
        comment="用户昵称",
    )

    avatar_url: Mapped[str | None] = mapped_column(
        Text,
        nullable=True,
        comment="头像 URL",
    )

    # ========== 业务追踪 ==========
    source: Mapped[str] = mapped_column(
        String(32),
        default="unknown",
        nullable=False,
        comment="注册来源",
    )

    invited_by: Mapped[str | None] = mapped_column(
        String(36),
        nullable=True,
        comment="邀请人 user_id",
    )

    # ========== 时间戳（补充）==========
    last_login_at: Mapped[datetime | None] = mapped_column(
        DateTime(timezone=True),
        nullable=True,
        comment="最后登录时间",
    )

    last_login_ip: Mapped[str | None] = mapped_column(
        String(45),
        nullable=True,
        comment="最后登录 IP（IPv6 最大 45 字符）",
    )

    deleted_at: Mapped[datetime | None] = mapped_column(
        DateTime(timezone=True),
        nullable=True,
        comment="注销时间（软删除标记）",
    )

    # ========== 冗余字段（备用）==========
    extra: Mapped[dict] = mapped_column(
        JSONB,
        default=dict,
        nullable=False,
        comment="冗余字段，备用",
    )

    def __repr__(self) -> str:
        return f"<User(id={self.id}, mobile={self.mobile}, status={self.status})>"

    @property
    def is_active(self) -> bool:
        """是否有效用户"""
        return self.status == UserStatus.ACTIVE.value

    @property
    def display_name(self) -> str:
        """对外展示的名称"""
        return self.nickname or f"用户_{self.mobile[-4:]}"



