# -*- coding: utf-8 -*-
"""中台：积分商城商品 + 兑换订单管理。"""
import datetime
from flask import render_template, request, redirect, url_for, flash
from flask_login import login_required

from app.models import Product, ExchangeOrder, Staff
from app.extensions import db
from app.admin import bp
from app.admin.views import _admin_only
from app.admin.admins import _super_only
from app.services import log_action, add_points


# -------------------- 商品 --------------------

@bp.route("/products")
@login_required
def products():
    _admin_only()
    q = request.args.get("q", "").strip()
    query = Product.query
    if q:
        query = query.filter(Product.name.contains(q))
    products = query.order_by(Product.id.desc()).all()
    return render_template("admin/product_list.html", products=products, q=q, active="products")


@bp.route("/products/new", methods=["GET", "POST"])
@bp.route("/products/<int:id>/edit", methods=["GET", "POST"])
@login_required
def product_edit(id=None):
    _admin_only()
    p = Product.query.get_or_404(id) if id else Product(status="on", stock=0, points_cost=100)
    if request.method == "POST":
        p.name = request.form.get("name", "").strip()
        p.image_url = request.form.get("image_url", "").strip()
        p.points_cost = request.form.get("points_cost", 100, type=int)
        p.stock = request.form.get("stock", 0, type=int)
        p.category = request.form.get("category", "").strip()
        p.description = request.form.get("description", "").strip()
        p.status = request.form.get("status", "on")
        if not p.name:
            flash("商品名称必填", "danger")
        else:
            if id is None:
                db.session.add(p)
            db.session.commit()
            log_action("product_create" if id is None else "product_edit",
                       target_type="product", target_id=p.id, summary="商品：%s" % p.name)
            flash("已保存", "success")
            return redirect(url_for("admin.products"))
    return render_template("admin/product_form.html", p=p, active="products", is_new=(id is None))


@bp.route("/products/<int:id>/delete", methods=["POST"])
@login_required
def product_delete(id):
    _admin_only()
    p = Product.query.get_or_404(id)
    # 有兑换记录的商品不可删除：数据库外键约束会抛 IntegrityError(500)，
    # 且删掉会破坏历史订单的商品名展示。引导改为下架。
    order_count = ExchangeOrder.query.filter_by(product_id=id).count()
    if order_count:
        flash("该商品已有 %d 条兑换记录，无法删除。超级管理员可先到「兑换订单」删除这些订单后重试；或改为下架。" % order_count, "warning")
        return redirect(url_for("admin.products"))
    name = p.name
    try:
        db.session.delete(p)
        log_action("delete_product", target_type="product", target_id=id,
                   summary="删除商品：%s" % name, commit=False)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        flash("删除失败：%s" % e, "danger")
        return redirect(url_for("admin.products"))
    flash("已删除", "success")
    return redirect(url_for("admin.products"))


@bp.route("/products/<int:id>/status", methods=["POST"])
@login_required
def product_toggle_status(id):
    """一键上架/下架切换。有兑换记录不能删时的推荐替代操作。"""
    _admin_only()
    p = Product.query.get_or_404(id)
    p.status = "off" if p.status == "on" else "on"
    log_action("product_status", target_type="product", target_id=id,
               summary="商品：%s → %s" % (p.name, "上架" if p.status == "on" else "下架"),
               commit=False)
    db.session.commit()
    flash("已%s" % ("上架" if p.status == "on" else "下架"), "success")
    return redirect(url_for("admin.products"))


# -------------------- 订单 --------------------

@bp.route("/orders")
@login_required
def orders():
    _admin_only()
    status = request.args.get("status", "").strip()
    query = ExchangeOrder.query.join(ExchangeOrder.staff).filter(Staff.deleted == False)
    if status:
        query = query.filter_by(status=status)
    orders = query.order_by(ExchangeOrder.id.desc()).limit(200).all()
    return render_template("admin/order_list.html", orders=orders, status=status, active="orders")


@bp.route("/orders/<int:id>/ship", methods=["POST"])
@login_required
def order_ship(id):
    _admin_only()
    o = ExchangeOrder.query.get_or_404(id)
    if o.status != "pending":
        flash("该订单状态不可发货", "danger")
        return redirect(url_for("admin.orders"))
    o.status = "shipped"
    o.tracking_no = request.form.get("tracking_no", "").strip()
    o.shipped_at = datetime.datetime.now()
    log_action("order_ship", target_type="order", target_id=id,
               summary="订单 #%d 发货，单号 %s" % (id, o.tracking_no or "无"), commit=False)
    db.session.commit()
    flash("已发货", "success")
    return redirect(url_for("admin.orders"))


@bp.route("/orders/<int:id>/complete", methods=["POST"])
@login_required
def order_complete(id):
    _admin_only()
    o = ExchangeOrder.query.get_or_404(id)
    if o.status == "shipped":
        o.status = "done"
        log_action("order_complete", target_type="order", target_id=id,
                   summary="订单 #%d 完成" % id, commit=False)
        db.session.commit()
        flash("已完成", "success")
    return redirect(url_for("admin.orders"))


@bp.route("/orders/<int:id>/delete", methods=["POST"])
@login_required
def order_delete(id):
    """删除兑换订单（仅超级管理员）。逆向兑换：退积分 + 还库存 + 删订单，一次事务。"""
    _super_only()
    o = ExchangeOrder.query.get_or_404(id)
    staff = o.staff
    product = o.product
    cost = o.points_cost or 0
    pname = product.name if product else "（商品已删除）"
    sname = staff.name if staff else "（店员已删除）"
    # 退积分（统一入口，保证余额与流水一致）；店员已删除则跳过
    if staff and cost:
        add_points(staff, cost, "exchange", ref_id=(product.id if product else None),
                   remark="删除订单 #%d 退回" % id, commit=False)
    # 还库存
    if product:
        product.stock = (product.stock or 0) + 1
    summary = "删除订单 #%d（%s 兑 %s，退 %d 积分、库存 +1）" % (id, sname, pname, cost)
    db.session.delete(o)
    log_action("order_delete", target_type="order", target_id=id,
               summary=summary, commit=False)
    db.session.commit()
    flash("已删除订单 #%d，退回 %d 积分给 %s、%s 库存 +1" % (id, cost, sname, pname), "success")
    return redirect(url_for("admin.orders"))
