"""帮助与反馈 endpoint。

路由前缀 `/api/v1/feedback`,需 Bearer 鉴权(反馈绑到登录用户,便于回访)。
  POST /  提交反馈(multipart:content 必填;contact 可选(原型改版后客户端已不再采集);images 可选 ≤6 张)
  GET /records  我的反馈历史(pending/adopted/rejected)

截图复用 [app.core.media] 落盘到 /media/feedback/。
"""
from __future__ import annotations

import logging

from fastapi import APIRouter, File, Form, HTTPException, Query, UploadFile

from app.api.deps import CurrentUser, DbSession
from app.core import media
from app.repositories import feedback as feedback_repo
from app.repositories import feedback_qr as feedback_qr_repo
from app.schemas.feedback import (
    FeedbackOut,
    FeedbackQrConfigOut,
    FeedbackRecordCountsOut,
    FeedbackRecordOut,
    FeedbackRecordsOut,
)

logger = logging.getLogger("shagua.feedback")

router = APIRouter(prefix="/api/v1/feedback", tags=["feedback"])

_MAX_IMAGES = 6
_CONTENT_MAX = 200
_CONTACT_MAX = 128
_VALID_RECORD_STATUS = {"pending", "adopted", "rejected"}


def _app_status(db_status: str) -> str:
    return {
        "new": "pending",
        "handled": "adopted",
        "approved": "adopted",
    }.get(db_status, db_status)


def _record_out(fb) -> FeedbackRecordOut:
    return FeedbackRecordOut(
        id=fb.id,
        content=fb.content,
        images=fb.images or [],
        status=_app_status(fb.status),
        reject_reason=getattr(fb, "reject_reason", None),
        reward_coins=getattr(fb, "reward_coins", None),
        created_at=fb.created_at,
    )


@router.post("", response_model=FeedbackOut, summary="提交反馈")
async def submit_feedback(
    user: CurrentUser,
    db: DbSession,
    content: str = Form(...),
    # 原型改版后客户端不再采集联系方式;保留字段以兼容旧端 + 后续可能复用,默认空串。
    contact: str = Form(default=""),
    images: list[UploadFile] = File(default=[]),
) -> FeedbackOut:
    content = content.strip()
    contact = contact.strip()
    if not content:
        raise HTTPException(status_code=400, detail="反馈内容不能为空")
    if len(content) > _CONTENT_MAX:
        raise HTTPException(status_code=400, detail="反馈内容过长")
    if len(contact) > _CONTACT_MAX:
        raise HTTPException(status_code=400, detail="联系方式过长")

    files = [f for f in (images or []) if f is not None and f.filename]
    if len(files) > _MAX_IMAGES:
        raise HTTPException(status_code=400, detail=f"最多上传 {_MAX_IMAGES} 张图片")

    urls: list[str] = []
    for f in files:
        data = await f.read()
        try:
            urls.append(media.save_feedback_image(user.id, data))
        except media.MediaError as e:
            raise HTTPException(status_code=400, detail=str(e)) from e

    fb = feedback_repo.create_feedback(
        db, user_id=user.id, content=content, contact=contact, images=urls,
    )
    logger.info("feedback id=%d user_id=%d images=%d", fb.id, user.id, len(urls))
    return FeedbackOut.model_validate(fb)


@router.get("/config", response_model=FeedbackQrConfigOut, summary="反馈页二维码卡配置")
def feedback_config(user: CurrentUser, db: DbSession) -> FeedbackQrConfigOut:
    """运营后台配的反馈页「加群二维码」卡(开关 + 二维码图 + 三行文案)。客户端进反馈页时拉取。"""
    return FeedbackQrConfigOut(**feedback_qr_repo.get_config(db))


@router.get("/records", response_model=FeedbackRecordsOut, summary="我的反馈历史")
def feedback_records(
    user: CurrentUser,
    db: DbSession,
    status: str | None = Query(default=None),
) -> FeedbackRecordsOut:
    if status is not None and status not in _VALID_RECORD_STATUS:
        raise HTTPException(status_code=400, detail="invalid status")

    all_records = [_record_out(fb) for fb in feedback_repo.list_feedback(db, user_id=user.id)]
    counts = FeedbackRecordCountsOut(
        all=len(all_records),
        pending=sum(1 for r in all_records if r.status == "pending"),
        adopted=sum(1 for r in all_records if r.status == "adopted"),
        rejected=sum(1 for r in all_records if r.status == "rejected"),
    )
    records = [r for r in all_records if r.status == status] if status else all_records
    return FeedbackRecordsOut(records=records, counts=counts)
