# -*- coding: utf-8 -*-
"""中台：案例投稿审核（通过发 50 积分 / 驳回 / super 删除扣回）。"""
import datetime
from flask import render_template, request, redirect, url_for, flash, abort
from flask_login import login_required, current_user

from app.models import CaseSubmission, Staff, Setting, Store, Chain
from app.extensions import db
from app.services import add_points, log_action, get_setting_int
from app.admin import bp
from app.admin.views import _admin_only
from app.admin.admins import _super_only
from app.region_data import CHINA_REGION


CASE_REWARD = 50


@bp.route("/cases")
@login_required
def cases():
    _admin_only()
    status = request.args.get("status", "pending").strip()
    year = request.args.get("year", "").strip()
    month = request.args.get("month", "").strip()
    chain = request.args.get("chain", "").strip()
    province = request.args.get("province", "").strip()
    city = request.args.get("city", "").strip()
    sq = request.args.get("sq", "").strip()
    query = CaseSubmission.query.join(CaseSubmission.staff).filter(Staff.deleted == False)
    if status == "reviewed":
        query = query.filter(CaseSubmission.status.in_(("approved", "rejected")))
    elif status in ("pending", "approved", "rejected"):
        query = query.filter(CaseSubmission.status == status)
    if year and month:
        start = datetime.date(int(year), int(month), 1)
        end = datetime.date(int(year) + 1, 1, 1) if int(month) == 12 else datetime.date(int(year), int(month) + 1, 1)
        query = query.filter(CaseSubmission.created_at >= start, CaseSubmission.created_at < end)
    elif year:
        query = query.filter(CaseSubmission.created_at >= datetime.date(int(year), 1, 1),
                             CaseSubmission.created_at < datetime.date(int(year) + 1, 1, 1))
    elif month:
        query = query.filter(db.extract('month', CaseSubmission.created_at) == int(month))
    if chain:
        query = query.join(Store, Staff.store_id == Store.id).filter(Store.chain_id == int(chain))
    if province:
        query = query.filter(Staff.province == province)
    if city:
        query = query.filter(Staff.city == city)
    if sq:
        query = query.filter(db.or_(Staff.name.contains(sq), Staff.phone.contains(sq)))
    cases = query.order_by(CaseSubmission.id.desc()).limit(200).all()
    limit = get_setting_int("case_monthly_limit", 100)
    chains = Chain.query.order_by(Chain.name).all()
    years = sorted({str(s[0].year) for s in
                    CaseSubmission.query.with_entities(CaseSubmission.created_at).all() if s[0]}, reverse=True)
    return render_template("admin/case_review.html", cases=cases, status=status, limit=limit,
                           year=year, month=month, chain=chain, province=province, city=city, sq=sq,
                           chains=chains, years=years, china_region=CHINA_REGION, active="cases")


@bp.route("/cases/rule", methods=["POST"])
@login_required
def case_rule():
    """设置患教投稿每人每月上限（0=禁用）。"""
    _admin_only()
    limit = request.form.get("limit", 100, type=int)
    if limit < 0:
        limit = 0
    row = Setting.query.get("case_monthly_limit")
    if not row:
        row = Setting(key="case_monthly_limit")
        db.session.add(row)
    row.value = str(limit)
    db.session.commit()
    log_action("case_rule", target_type="setting", summary="患教投稿每月限额设为 %d 次" % limit)
    flash("已保存（每月每人最多投稿 %d 次，0=禁用）" % limit, "success")
    return redirect(url_for("admin.cases"))


@bp.route("/cases/<int:id>/approve", methods=["POST"])
@login_required
def case_approve(id):
    _admin_only()
    c = db.session.query(CaseSubmission).filter(CaseSubmission.id == id).with_for_update().first()
    if not c:
        abort(404)
    if c.status != "pending":
        flash("该投稿已处理", "danger")
        return redirect(url_for("admin.cases"))
    c.status = "approved"
    c.reviewer_id = current_user.id
    c.reviewed_at = datetime.datetime.now()
    c.points_earned = CASE_REWARD
    ok = add_points(c.staff, CASE_REWARD, "case", ref_id=c.id,
                    remark="案例投稿奖励（%s）" % c.disease, commit=False)
    if not ok:
        db.session.rollback()
        flash("发分失败，请重试", "danger")
        return redirect(url_for("admin.cases"))
    log_action("case_approve", target_type="case_submission", target_id=id,
               summary="通过 %s 的案例投稿(%s)，发分 %d" % (
                   c.staff.name if c.staff else "?", c.disease, CASE_REWARD), commit=False)
    db.session.commit()
    flash("已通过，发放积分 %d" % CASE_REWARD, "success")
    return redirect(url_for("admin.cases"))


@bp.route("/cases/<int:id>/reject", methods=["POST"])
@login_required
def case_reject(id):
    _admin_only()
    c = CaseSubmission.query.get_or_404(id)
    if c.status != "pending":
        return redirect(url_for("admin.cases"))
    c.status = "rejected"
    c.reviewer_id = current_user.id
    c.reviewed_at = datetime.datetime.now()
    c.reject_reason = request.form.get("reason", "").strip()
    log_action("case_reject", target_type="case_submission", target_id=id,
               summary="驳回 %s 的案例投稿" % (c.staff.name if c.staff else "?"), commit=False)
    db.session.commit()
    flash("已驳回", "success")
    return redirect(url_for("admin.cases"))


@bp.route("/cases/<int:id>/delete", methods=["POST"])
@login_required
def case_delete(id):
    """删除案例投稿（仅超级管理员）。仅 approved 扣回已发积分。"""
    _super_only()
    c = CaseSubmission.query.get_or_404(id)
    staff = c.staff
    pts = c.points_earned or 0
    deduct = pts if c.status == "approved" else 0
    if deduct > 0 and staff:
        ok = add_points(staff, -deduct, "case", ref_id=c.id,
                        remark="删除案例投稿 #%d 扣回" % c.id, commit=False)
        if not ok:
            db.session.rollback()
            flash("无法删除：%s 积分余额不足，无法扣回 %d" % (staff.name, deduct), "danger")
            return redirect(url_for("admin.cases", status="reviewed"))
    summary = "删除案例投稿 #%d（%s，状态 %s，扣回 %d）" % (
        id, staff.name if staff else "？", c.status, deduct)
    db.session.delete(c)
    log_action("delete_case_submission", target_type="case_submission", target_id=id,
               summary=summary, commit=False)
    db.session.commit()
    flash("已删除，扣回 %d 积分" % deduct, "success")
    return redirect(url_for("admin.cases", status="reviewed"))
