import math
from flask import render_template, request, jsonify, redirect, url_for
from app.subadmin import subadmin_blueprint
from app.subadmin.auth import subadmin_login_required
from config.db_config import get_db_connection
from models.user_model import (
    get_dashboard_counts,
    get_dashboard_chart_data,
    get_event_config,
    get_site_assets,
)


# ── Dashboard ─────────────────────────────────────────────────────────────────

@subadmin_blueprint.route("/dashboard")
@subadmin_login_required
def dashboard():
    return render_template(
        "subadmin/dashboard.html",
        stats=get_dashboard_counts(),
        chart_data=get_dashboard_chart_data(),
        site_assets=get_site_assets(),
        event_data=get_event_config(),
    )


# ── Visitors ──────────────────────────────────────────────────────────────────

@subadmin_blueprint.route("/visitors")
@subadmin_login_required
def visitors():
    search = (request.args.get("search") or "").strip()
    limit  = request.args.get("limit", 25, type=int)
    page   = request.args.get("page",  1,  type=int)
    if limit not in [25, 50, 100]:
        limit = 25
    offset = (page - 1) * limit

    conn   = get_db_connection()
    cursor = conn.cursor(dictionary=True)

    params = []
    where  = ""
    if search:
        pattern = f"%{search}%"
        where   = "WHERE (vr.name LIKE %s OR vr.mobile_number LIKE %s OR vr.email LIKE %s)"
        params  = [pattern, pattern, pattern]

    cursor.execute(f"SELECT COUNT(*) AS c FROM visitors_registration vr {where}", params)
    total = (cursor.fetchone() or {}).get("c", 0)
    total_pages = math.ceil(total / limit) if total > 0 else 1

    cursor.execute(f"""
        SELECT
            vr.id, vr.name, vr.mobile_number, vr.email,
            u.s3_image_url AS face_photo,
            u.created_at   AS face_registered_at
        FROM visitors_registration vr
        LEFT JOIN users u
            ON LOWER(TRIM(u.email)) = LOWER(TRIM(vr.email))
            OR u.phone = vr.mobile_number
        {where}
        ORDER BY vr.id DESC
        LIMIT %s OFFSET %s
    """, params + [limit, offset])
    visitors = cursor.fetchall()
    cursor.close()
    conn.close()

    return render_template("subadmin/visitors.html",
        visitors=visitors, search=search,
        limit=limit, page=page,
        total=total, total_pages=total_pages,
    )


@subadmin_blueprint.route("/visitors/edit/<int:visitor_id>", methods=["GET", "POST"])
@subadmin_login_required
def edit_visitor(visitor_id):
    conn   = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    cursor.execute("SELECT * FROM visitors_registration WHERE id = %s", (visitor_id,))
    visitor = cursor.fetchone()

    if not visitor:
        cursor.close(); conn.close()
        return redirect(url_for("subadmin.visitors"))

    if request.method == "POST":
        name   = (request.form.get("name") or "").strip()
        mobile = (request.form.get("mobile_number") or "").strip()
        email  = (request.form.get("email") or "").strip()
        cursor.execute(
            "UPDATE visitors_registration SET name=%s, mobile_number=%s, email=%s WHERE id=%s",
            (name, mobile, email, visitor_id)
        )
        conn.commit()
        cursor.close(); conn.close()
        return redirect(url_for("subadmin.visitors"))

    cursor.close(); conn.close()
    return render_template("subadmin/visitors_edit.html", visitor=visitor)


# ── Consent ───────────────────────────────────────────────────────────────────

@subadmin_blueprint.route("/consent")
@subadmin_login_required
def consent():
    limit  = request.args.get("limit", 10, type=int)
    page   = request.args.get("page",  1,  type=int)
    search = (request.args.get("search") or "").strip()
    if limit not in [10, 25, 50]:
        limit = 10
    offset = (page - 1) * limit

    conn   = get_db_connection()
    cursor = conn.cursor(dictionary=True)

    cursor.execute("SELECT COUNT(*) AS c FROM visitors_registration")
    total_visitors = (cursor.fetchone() or {}).get("c", 0)

    cursor.execute("SELECT COUNT(*) AS c FROM consent_logs WHERE agreed=1")
    consented = (cursor.fetchone() or {}).get("c", 0)

    cursor.execute("""
        SELECT role, consent_msg FROM consent_messages
        WHERE is_active=1 GROUP BY role
    """)
    msgs = {r["role"]: r["consent_msg"] for r in cursor.fetchall()}

    search_sql = ""
    params = []
    if search:
        pattern    = f"%{search}%"
        search_sql = "WHERE (username LIKE %s OR user_email LIKE %s)"
        params     = [pattern, pattern]

    cursor.execute(f"SELECT COUNT(*) AS c FROM consent_logs {search_sql}", params)
    total_logs  = (cursor.fetchone() or {}).get("c", 0)
    total_pages = math.ceil(total_logs / limit) if total_logs > 0 else 1

    cursor.execute(f"""
        SELECT id, username, user_email, agreed, agreed_at
        FROM consent_logs {search_sql}
        ORDER BY agreed_at DESC
        LIMIT %s OFFSET %s
    """, params + [limit, offset])
    logs = cursor.fetchall()
    cursor.close(); conn.close()

    return render_template("subadmin/consent.html",
        total_visitors=total_visitors, consented_users=consented,
        consent_msgs=msgs, logs=logs,
        total_logs=total_logs, total_pages=total_pages,
        page=page, limit=limit, search=search,
    )


@subadmin_blueprint.route("/api/consent/message/<role>", methods=["GET"])
@subadmin_login_required
def get_consent(role):
    if role not in ("visitor", "admin", "photographer"):
        return jsonify({"error": "Invalid role"}), 400
    conn   = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    cursor.execute("""
        SELECT consent_msg FROM consent_messages
        WHERE role=%s AND is_active=1
        ORDER BY updated_at DESC LIMIT 1
    """, (role,))
    row = cursor.fetchone()
    cursor.close(); conn.close()
    return jsonify({"role": role, "consent_msg": row["consent_msg"] if row else ""})


@subadmin_blueprint.route("/api/consent/message/<role>", methods=["POST"])
@subadmin_login_required
def save_consent(role):
    if role not in ("visitor", "admin", "photographer"):
        return jsonify({"error": "Invalid role"}), 400
    payload = request.get_json(silent=True) or {}
    msg     = (payload.get("consent_msg") or "").strip()
    if not msg:
        return jsonify({"error": "Message cannot be empty"}), 400

    conn   = get_db_connection()
    cursor = conn.cursor()
    cursor.execute(
        "SELECT id FROM consent_messages WHERE role=%s ORDER BY updated_at DESC LIMIT 1",
        (role,)
    )
    existing = cursor.fetchone()
    if existing:
        cursor.execute(
            "UPDATE consent_messages SET consent_msg=%s, updated_at=NOW() WHERE id=%s",
            (msg, existing[0])
        )
        cursor.execute(
            "DELETE FROM consent_messages WHERE role=%s AND id!=%s",
            (role, existing[0])
        )
    else:
        cursor.execute(
            "INSERT INTO consent_messages (role, consent_msg, is_active) VALUES (%s,%s,1)",
            (role, msg)
        )
    conn.commit()
    cursor.close(); conn.close()
    return jsonify({"success": True, "message": f"Consent for {role} updated."})


# ── Visitors API ──────────────────────────────────────────────────────────────

@subadmin_blueprint.route("/api/visitors/add", methods=["POST"])
@subadmin_login_required
def add_visitor():
    data   = request.get_json(silent=True) or {}
    name   = (data.get("name") or "").strip()
    mobile = (data.get("mobile") or "").strip()
    email  = (data.get("email") or "").strip()
    if not name:
        return jsonify({"success": False, "message": "Name is required"}), 400
    if not email and not mobile:
        return jsonify({"success": False, "message": "Email or mobile required"}), 400
    conn   = get_db_connection()
    cursor = conn.cursor()
    cursor.execute(
        "INSERT INTO visitors_registration (name, mobile_number, email) VALUES (%s,%s,%s)",
        (name, mobile or None, email or None)
    )
    conn.commit()
    vid = cursor.lastrowid
    cursor.close(); conn.close()
    return jsonify({"success": True, "message": "Visitor added", "visitor_id": vid})