"""لوحة الأدمن (ويب) — تفعيل الكباتن وتمديد الاشتراك. المسار: /admin"""
import datetime as dt
import hmac
import secrets
from decimal import Decimal, InvalidOperation
from functools import wraps

from flask import (Blueprint, abort, current_app, flash, g, redirect, render_template,
                   request, session, url_for)
from werkzeug.security import check_password_hash, generate_password_hash

from auth import find_user_by_identifier, subscription_state
from db import execute, query_all, query_one
from utils import add_months, today_local

bp = Blueprint("admin", __name__)

STATE_LABELS = {"active": "فعّال", "grace": "فترة سماح", "expired": "منتهي", "inactive": "غير مفعّل"}


# ---------------- CSRF + الجلسة ----------------
def _csrf():
    if "csrf" not in session:
        session["csrf"] = secrets.token_hex(16)
    return session["csrf"]


@bp.app_context_processor
def _inject():
    return {"csrf_token": _csrf}


@bp.before_request
def _check_csrf():
    if request.method == "POST":
        sent = request.form.get("csrf", "")
        if not sent or not hmac.compare_digest(sent, session.get("csrf", "")):
            abort(400, "CSRF token invalid")


def admin_required(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
        uid = session.get("admin_id")
        admin = query_one("SELECT * FROM users WHERE id=%s AND role='admin' AND is_blocked=0",
                          (uid,)) if uid else None
        if not admin:
            session.pop("admin_id", None)
            return redirect(url_for("admin.login"))
        g.admin = admin
        return fn(*args, **kwargs)

    return wrapper


# ---------------- الدخول ----------------
@bp.route("/login", methods=["GET", "POST"])
def login():
    if request.method == "POST":
        user = find_user_by_identifier(request.form.get("identifier"))
        if (user and user["role"] == "admin" and not user["is_blocked"]
                and check_password_hash(user["password_hash"], request.form.get("password", ""))):
            session.clear()
            session["admin_id"] = user["id"]
            session.permanent = True
            return redirect(url_for("admin.captains"))
        flash("بيانات الدخول غير صحيحة", "error")
    return render_template("login.html")


@bp.post("/logout")
def logout():
    session.clear()
    return redirect(url_for("admin.login"))


# ---------------- الكباتن ----------------
@bp.get("/")
@admin_required
def captains():
    q = (request.args.get("q") or "").strip()
    sql = """SELECT u.id, u.full_name, u.username, u.phone, c.is_active, c.paid_until,
                    (SELECT COUNT(*) FROM trainees t WHERE t.captain_id = u.id) AS trainees_count
             FROM captains c JOIN users u ON u.id = c.user_id"""
    args = []
    if q:
        sql += " WHERE u.full_name LIKE %s OR u.username LIKE %s OR u.phone LIKE %s"
        args = [f"%{q}%"] * 3
    rows = query_all(sql, args)

    today = today_local()
    counts = {k: 0 for k in STATE_LABELS}
    for r in rows:
        r["state"] = subscription_state(r)
        counts[r["state"]] += 1
        if r["paid_until"]:
            n = (r["paid_until"] - today).days
            r["days_text"] = f"متبقي {n} يوم" if n >= 0 else f"منتهي منذ {-n} يوم"
    # الأقرب انتهاءً (والذين بلا اشتراك) أولاً
    rows.sort(key=lambda r: (r["paid_until"] is not None, r["paid_until"] or dt.date.min))
    return render_template("captains.html", captains=rows, q=q, counts=counts,
                           labels=STATE_LABELS, price=current_app.config["SUBSCRIPTION_PRICE"])


def _get_captain_for_update(uid):
    c = query_one("SELECT * FROM captains WHERE user_id=%s FOR UPDATE", (uid,))
    if not c:
        abort(404)
    return c


@bp.post("/captains/<int:uid>/extend")
@admin_required
def extend(uid):
    """تفعيل/تمديد: يمدّد من نهاية الاشتراك الحالي إن كان ساري، وإلا من اليوم."""
    c = _get_captain_for_update(uid)
    try:
        months = max(1, min(int(request.form.get("months", 1)), 12))
    except ValueError:
        months = 1
    raw_amount = (request.form.get("amount") or "").strip()
    try:
        amount = Decimal(raw_amount) if raw_amount else Decimal(current_app.config["SUBSCRIPTION_PRICE"]) * months
    except InvalidOperation:
        amount = Decimal(0)

    today = today_local()
    start = c["paid_until"] if c["paid_until"] and c["paid_until"] >= today else today
    new_until = add_months(start, months)
    execute("UPDATE captains SET is_active=1, paid_until=%s, activated_at=NOW() WHERE user_id=%s",
            (new_until, uid))
    execute("""INSERT INTO subscription_payments (captain_id, admin_id, months, amount, period_end)
               VALUES (%s,%s,%s,%s,%s)""", (uid, g.admin["id"], months, amount, new_until))
    flash(f"تم التفعيل حتى {new_until}", "ok")
    return redirect(request.referrer or url_for("admin.captains"))


@bp.post("/captains/<int:uid>/deactivate")
@admin_required
def deactivate(uid):
    _get_captain_for_update(uid)
    execute("UPDATE captains SET is_active=0 WHERE user_id=%s", (uid,))
    flash("تم إيقاف الكابتن وقفل حسابه", "ok")
    return redirect(request.referrer or url_for("admin.captains"))


@bp.post("/captains/<int:uid>/reset-password")
@admin_required
def reset_password(uid):
    _get_captain_for_update(uid)
    temp = secrets.token_urlsafe(6)
    execute("UPDATE users SET password_hash=%s WHERE id=%s", (generate_password_hash(temp), uid))
    flash(f"كلمة المرور المؤقتة: {temp}  (أعطها للكابتن ليغيّرها بعد الدخول)", "ok")
    return redirect(request.referrer or url_for("admin.captains"))


# ---------------- الدفعات ----------------
@bp.get("/payments")
@admin_required
def payments():
    rows = query_all("""SELECT p.id, p.months, p.amount, p.period_end, p.paid_on, u.full_name
                        FROM subscription_payments p JOIN users u ON u.id = p.captain_id
                        ORDER BY p.id DESC LIMIT 200""")
    total = query_one("SELECT COALESCE(SUM(amount),0) AS total FROM subscription_payments")["total"]
    return render_template("payments.html", payments=rows, total=total)
