"""用户反馈表(帮助与反馈)。

每条 = 用户一次提交。content 必填;contact 原为必填(微信/QQ/手机),原型改版后客户端不再采集,
新数据存空串(列保持 NOT NULL,免迁移;历史数据仍有值);images 为可选的截图 URL 列表
(/media/feedback/...,JSON 存)。status: pending(审核中)/adopted(已采纳)/rejected(未采纳)。
"""
from __future__ import annotations

from datetime import datetime

from sqlalchemy import JSON, DateTime, ForeignKey, Integer, String, Text, func
from sqlalchemy.orm import Mapped, mapped_column

from app.db.base import Base


class Feedback(Base):
    __tablename__ = "feedback"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    user_id: Mapped[int] = mapped_column(
        Integer, ForeignKey("user.id"), index=True, nullable=False
    )
    content: Mapped[str] = mapped_column(Text, nullable=False)
    contact: Mapped[str] = mapped_column(String(128), nullable=False)
    # 反馈来源入口:profile(「我的」页反馈入口)/ comparison(比价结果页反馈入口)。
    # admin 据此展示/筛选「反馈类型」。旧数据与「我的」页反馈均为 profile(server_default)。
    # 客户端显式传 source 优先;未传时由 scene 有无派生(见 api/v1/feedback.submit_feedback)。
    source: Mapped[str] = mapped_column(
        String(16), nullable=False, default="profile", server_default="profile", index=True
    )
    # 比价反馈的「问题场景」(找错商品/优惠不对/比价太慢…),比价结果页反馈才有;普通反馈为 NULL。
    scene: Mapped[str | None] = mapped_column(String(32), nullable=True)
    # 截图 URL 列表(相对路径,如 ["/media/feedback/u1_ab12.jpg"]);无图为 None
    images: Mapped[list[str] | None] = mapped_column(JSON, nullable=True)
    # 提交时的端环境快照(admin 排查用;客户端改版带上后的新反馈才有,历史数据为 NULL)
    app_version: Mapped[str | None] = mapped_column(String(32), nullable=True)  # 我们 app versionName
    device_model: Mapped[str | None] = mapped_column(String(64), nullable=True)  # Build.MODEL
    rom_name: Mapped[str | None] = mapped_column(String(32), nullable=True)  # OemDetector os:ColorOS/MIUI/...
    android_version: Mapped[str | None] = mapped_column(String(16), nullable=True)  # Build.VERSION.RELEASE
    # pending(审核中) / adopted(已采纳) / rejected(未采纳)
    status: Mapped[str] = mapped_column(String(16), nullable=False, default="pending", index=True)
    reject_reason: Mapped[str | None] = mapped_column(String(256), nullable=True)
    reward_coins: Mapped[int | None] = mapped_column(Integer, nullable=True)
    # 审核批注:采纳时可写采纳要点,未采纳时也可保留运营侧备注
    review_note: Mapped[str | None] = mapped_column(String(256), nullable=True)
    # 运营给用户的回复留言(**用户端可见**,采纳/未采纳都可填,随「我的反馈」历史下发)。
    # 与 review_note(内部备注,用户不可见)、reject_reason(未采纳原因)区分开。
    admin_reply: Mapped[str | None] = mapped_column(String(256), nullable=True)
    reviewed_by_admin_id: Mapped[int | None] = mapped_column(
        Integer, ForeignKey("admin_user.id"), nullable=True
    )
    reviewed_at: Mapped[datetime | None] = mapped_column(
        DateTime(timezone=True), nullable=True
    )

    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), index=True, nullable=False
    )

    def __repr__(self) -> str:  # pragma: no cover
        return f"<Feedback id={self.id} user_id={self.user_id} status={self.status}>"
