# -*- coding: utf-8 -*-
"""中台：朋友圈集赞任务管理 + 提交审核（按阶梯发积分）。"""
import json
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 LikeTask, LikeSubmission, Staff, Store, Chain
from app.extensions import db
from app.services import add_points, calc_like_reward, log_action
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


# -------------------- 任务管理 --------------------

@bp.route("/likes/tasks")
@login_required
def like_tasks():
    _admin_only()
    tasks = LikeTask.query.order_by(LikeTask.id.desc()).all()
    return render_template("admin/like_task_list.html", tasks=tasks, active="likes")


@bp.route("/likes/tasks/new", methods=["GET", "POST"])
@bp.route("/likes/tasks/<int:id>/edit", methods=["GET", "POST"])
@login_required
def like_task_edit(id=None):
    _admin_only()
    t = LikeTask.query.get_or_404(id) if id else LikeTask(status="open")
    if request.method == "POST":
        t.title = request.form.get("title", "").strip()
        t.content = request.form.get("content", "").strip()
        t.image_url = request.form.get("image_url", "").strip()
        # reward_rules：解析 "赞数=积分" 多行
        raw = request.form.get("reward_rules", "").strip()
        rules = {}
        for line in raw.replace(",", "\n").replace("，", "\n").split("\n"):
            line = line.strip()
            if "=" in line:
                k, v = line.split("=", 1)
                try:
                    rules[str(int(k.strip()))] = int(v.strip())
                except ValueError:
                    pass
        t.reward_rules = json.dumps(rules, ensure_ascii=False) if rules else None
        dl = request.form.get("deadline", "").strip()
        t.deadline = datetime.datetime.strptime(dl, "%Y-%m-%dT%H:%M") if dl else None
        t.status = request.form.get("status", "open")
        if not t.title:
            flash("任务标题必填", "danger")
        else:
            if id is None:
                db.session.add(t)
            db.session.commit()
            flash("已保存", "success")
            return redirect(url_for("admin.like_tasks"))
    return render_template("admin/like_task_form.html", t=t, active="likes", is_new=(id is None))


@bp.route("/likes/tasks/<int:id>/delete", methods=["POST"])
@login_required
def like_task_delete(id):
    _admin_only()
    t = LikeTask.query.get_or_404(id)
    name = t.title
    db.session.delete(t)
    log_action("delete_like_task", target_type="like_task", target_id=id,
               summary="删除集赞任务：%s" % name, commit=False)
    db.session.commit()
    flash("已删除", "success")
    return redirect(url_for("admin.like_tasks"))


# -------------------- 提交审核 --------------------

@bp.route("/likes")
@login_required
def likes():
    _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 = LikeSubmission.query.join(LikeSubmission.staff).filter(Staff.deleted == False)
    if status == "reviewed":
        query = query.filter(LikeSubmission.status.in_(("approved", "rejected")))
    elif status in ("pending", "approved", "rejected"):
        query = query.filter(LikeSubmission.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(LikeSubmission.created_at >= start, LikeSubmission.created_at < end)
    elif year:
        query = query.filter(LikeSubmission.created_at >= datetime.date(int(year), 1, 1),
                             LikeSubmission.created_at < datetime.date(int(year) + 1, 1, 1))
    elif month:
        query = query.filter(db.extract('month', LikeSubmission.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)))
    subs = query.order_by(LikeSubmission.id.desc()).limit(200).all()
    chains = Chain.query.order_by(Chain.name).all()
    years = sorted({str(s[0].year) for s in
                    LikeSubmission.query.with_entities(LikeSubmission.created_at).all() if s[0]}, reverse=True)
    return render_template("admin/like_review.html", subs=subs, status=status,
                           year=year, month=month, chain=chain, province=province, city=city, sq=sq,
                           chains=chains, years=years, china_region=CHINA_REGION, active="likes")


@bp.route("/likes/<int:id>/approve", methods=["POST"])
@login_required
def like_approve(id):
    _admin_only()
    # 行锁串行化并发审核：锁内复查 status，防止双击/并发重复发分
    sub = db.session.query(LikeSubmission).filter(
        LikeSubmission.id == id).with_for_update().first()
    if not sub:
        abort(404)
    if sub.status != "pending":
        flash("该提交已处理", "danger")
        return redirect(url_for("admin.likes"))
    task = sub.task
    reward = calc_like_reward(task.reward_rules if task else None, sub.claimed_likes)
    sub.status = "approved"
    sub.reviewer_id = current_user.id
    sub.reviewed_at = datetime.datetime.now()
    sub.points_earned = reward
    if reward > 0:
        # commit=False：审核状态 + 发分(余额+流水) + 日志 同一事务提交
        ok = add_points(sub.staff, reward, "like", ref_id=sub.id,
                        remark="集赞奖励：%s（%d赞）" % (task.title if task else "", sub.claimed_likes),
                        commit=False)
        if not ok:
            db.session.rollback()
            flash("发分失败，请重试", "danger")
            return redirect(url_for("admin.likes"))
    log_action("like_approve", target_type="like_submission", target_id=id,
               summary="通过 %s 的集赞，发分 %d" % (sub.staff.name if sub.staff else "?", reward),
               commit=False)
    db.session.commit()
    flash("已通过，发放积分 %d" % reward, "success")
    return redirect(url_for("admin.likes"))


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


@bp.route("/likes/<int:id>/delete", methods=["POST"])
@login_required
def like_delete(id):
    """删除集赞提交（仅超级管理员）。仅 approved 扣回已发积分；rejected 未发分不扣。"""
    _super_only()
    sub = LikeSubmission.query.get_or_404(id)
    staff = sub.staff
    pts = sub.points_earned or 0
    deduct = pts if sub.status == "approved" else 0
    if deduct > 0 and staff:
        ok = add_points(staff, -deduct, "like", ref_id=sub.id,
                        remark="删除集赞提交 #%d 扣回" % sub.id, commit=False)
        if not ok:
            db.session.rollback()
            flash("无法删除：%s 当前积分余额不足，无法扣回 %d 积分" % (staff.name, deduct), "danger")
            return redirect(url_for("admin.likes", status="reviewed"))
    summary = "删除集赞提交 #%d（%s，状态 %s，扣回 %d 积分）" % (
        id, staff.name if staff else "？", sub.status, deduct)
    db.session.delete(sub)
    log_action("delete_like_submission", target_type="like_submission", target_id=id,
               summary=summary, commit=False)
    db.session.commit()
    flash("已删除集赞提交 #%d，扣回 %d 积分" % (id, deduct), "success")
    return redirect(url_for("admin.likes", status="reviewed"))
