from flask import (Blueprint, render_template, request,
                   redirect, url_for, session, jsonify, flash)
import bcrypt
from ..decorators import admin_required
from ..db import (
    get_all_clients, get_all_users_by_role, add_user,
    toggle_user_active, reset_user_password, delete_user,
    get_client_access_list, grant_report_access, revoke_report_access,
    get_audit_log, get_dashboard_stats, log_action,
    get_all_unique_reports, update_report_meta,
    auto_grant_all_reports_for_client, batch_grant_report_access
)
from ..ssrs import get_folders, get_folder_reports, get_report_params
from ..config import ROLE_ADMIN, ROLE_DBA, ROLE_CLIENT

admin_bp = Blueprint("admin", __name__, url_prefix="/admin")

# ── DASHBOARD___________________________________________________

@admin_bp.route("/")
@admin_required
def dashboard():
    stats = get_dashboard_stats()
    return render_template("admin/dashboard.html",
                           stats=stats,
                           admin_name=session["user_name"])

# ── CLIENT MANAGEMENT ─────────────────────────────────────────────

@admin_bp.route("/clients")
@admin_required
def clients():
    clients = get_all_clients()
    return render_template("admin/clients.html",
                           clients=clients,
                           admin_name=session["user_name"])

@admin_bp.route("/clients/add", methods=["POST"])
@admin_required
def add_client():
    f = request.form
    pw_hash = bcrypt.hashpw(f["password"].encode(), bcrypt.gensalt()).decode()
    ssrs_folder = f.get("ssrs_folder", "").strip()
    new_id = add_user(
        username = f["username"].strip(),
        password_hash = pw_hash,
        full_name = f["full_name"].strip(),
        email = f.get("email", "").strip(),
        role_id = ROLE_CLIENT,
        ssrs_folder = ssrs_folder,
        created_by = session["user_id"],
        client_db = f.get("client_db", "").strip() or None
    )
    # Auto-grant: SSRS folder se sab reports grant karo (backup skip)
    granted = auto_grant_all_reports_for_client(
        new_id, granted_by=session["user_id"], ssrs_folder=ssrs_folder
    )
    log_action(session["user_id"], "ADD_CLIENT",
               report_name=f["username"], ip=request.remote_addr,
               extra=f"auto_granted={granted}")
    flash(f"Client '{f['full_name']}' added successfully. {granted} reports auto-granted.", "success")
    return redirect(url_for("admin.clients"))

@admin_bp.route("/clients/<int:uid>/regrant-all", methods=["POST"])
@admin_required
def regrant_all(uid):
    """Existing client ke liye SSRS folder se sab reports re-grant karo."""
    from ..db import get_user_by_id
    client = get_user_by_id(uid)
    if not client:
        return jsonify({"success": False, "error": "Client not found"}), 404
    ssrs_folder = client.get("ssrs_folder", "") or ""
    granted = auto_grant_all_reports_for_client(uid, granted_by=session["user_id"],
                                                 ssrs_folder=ssrs_folder)
    log_action(session["user_id"], "REGRANT_ALL",
               report_name=client.get("username", ""), ip=request.remote_addr,
               extra=f"granted={granted}")
    flash(f"{granted} reports granted to {client['full_name']}.", "success")
    return redirect(url_for("admin.clients"))


    toggle_user_active(uid)
    return redirect(url_for("admin.clients"))

@admin_bp.route("/clients/<int:uid>/reset-password", methods=["POST"])
@admin_required
def reset_password(uid):
    new_pw = request.form.get("new_password", "")
    if len(new_pw) < 6:
        return jsonify({"success": False, "error": "Password too short"}), 400
    pw_hash = bcrypt.hashpw(new_pw.encode(), bcrypt.gensalt()).decode()
    reset_user_password(uid, pw_hash)
    log_action(session["user_id"], "RESET_PASSWORD", ip=request.remote_addr)
    return jsonify({"success": True})

@admin_bp.route("/clients/<int:uid>/delete", methods=["POST"])
@admin_required
def delete_client(uid):
    delete_user(uid)
    flash("Client deactivated.", "info")
    return redirect(url_for("admin.clients"))

# ── CLIENT ACCESS MANAGEMENT ──────────────────────────────────────

@admin_bp.route("/clients/<int:uid>/access")
@admin_required
def client_access(uid):
    from ..db import get_user_by_id
    client  = get_user_by_id(uid)
    if not client or client["role_id"] != ROLE_CLIENT:
        flash("Client not found.", "error")
        return redirect(url_for("admin.clients"))
    access_list = get_client_access_list(uid)
    return render_template("admin/client_access.html",
                           client=client,
                           access_list=access_list,
                           admin_name=session["user_name"])

@admin_bp.route("/access/revoke/<int:access_id>", methods=["POST"])
@admin_required
def revoke_access(access_id):
    revoke_report_access(access_id)
    log_action(session["user_id"], "REVOKE_ACCESS", ip=request.remote_addr)
    ref = request.referrer or url_for("admin.clients")
    return redirect(ref)


@admin_bp.route("/clients/<int:uid>/bulk-access")
@admin_required
def client_bulk_access(uid):
    from ..db import get_user_by_id
    client = get_user_by_id(uid)
    if not client or client["role_id"] != ROLE_CLIENT:
        flash("Client not found.", "error")
        return redirect(url_for("admin.clients"))
    # Get already-granted paths for this client
    access_list = get_client_access_list(uid)
    already_granted = [a["report_path"] for a in access_list if a["is_active"]]
    return render_template("admin/client_bulk_access.html",
                           client=client,
                           already_granted=already_granted,
                           admin_name=session["user_name"])

# ── REPORT BROWSER ────────────────────────────────────────────────

@admin_bp.route("/report-browser")
@admin_required
def report_browser():
    folders = get_folders()
    clients = get_all_clients()
    return render_template("admin/report_browser.html",
                           folders=folders,
                           clients=clients,
                           admin_name=session["user_name"])

# ── REPORT BROWSER: AJAX endpoints ────────────────────────────────

@admin_bp.route("/api/folders/<path:folder_path>/reports")
@admin_required
def api_folder_reports(folder_path):
    """Return reports JSON for a given folder path."""
    reports = get_folder_reports("/" + folder_path)
    return jsonify(reports)

@admin_bp.route("/api/reports/<report_id>/params")
@admin_required
def api_report_params(report_id):
    params = get_report_params(report_id)
    return jsonify(params)

@admin_bp.route("/api/grant-access", methods=["POST"])
@admin_required
def api_grant_access():
    data = request.json
    if not data:
        return jsonify({"success": False, "error": "No data"}), 400

    required = ["client_id", "report_path", "report_name", "category"]
    for key in required:
        if not data.get(key):
            return jsonify({"success": False, "error": f"Missing: {key}"}), 400

    ok = grant_report_access(
        client_id  = int(data["client_id"]),
        report_id  = data.get("report_id", ""),
        report_path = data["report_path"],
        report_name = data["report_name"],
        category = data["category"].strip(),
        granted_by = session["user_id"]
    )
    if not ok:
        return jsonify({"success": False, "error": "Already granted or DB error"}), 409

    log_action(session["user_id"], "GRANT_ACCESS",
               report_name=data["report_name"], ip=request.remote_addr,
               extra=f"client={data['client_id']} cat={data['category']}")
    return jsonify({"success": True})

@admin_bp.route("/api/batch-grant-access", methods=["POST"])
@admin_required
def api_batch_grant_access():
    data = request.json or {}
    client_id = data.get("client_id")
    reports   = data.get("reports", [])
    category  = (data.get("category") or "").strip()

    if not client_id or not reports or not category:
        return jsonify({"success": False, "error": "Missing client_id, reports, or category"}), 400

    result = batch_grant_report_access(
        client_id  = int(client_id),
        reports    = reports,
        category   = category,
        granted_by = session["user_id"]
    )
    log_action(session["user_id"], "BATCH_GRANT_ACCESS",
               ip=request.remote_addr,
               extra=f"client={client_id} cat={category} ok={result['ok']} skip={result['skip']}")
    return jsonify({"success": True, **result})

# ── AUDIT LOG ─────────────────────────────────────────────────────

@admin_bp.route("/audit")
@admin_required
def audit():
    logs = get_audit_log(limit=200)
    return render_template("admin/audit.html",
                           logs=logs,
                           admin_name=session["user_name"])

# ── REPORT MASTER ──────────────────────────────────────────────────

@admin_bp.route("/report-master")
@admin_required
def report_master():
    """Page for admin to set display names and categories for all reports."""
    reports = get_all_unique_reports()
    return render_template("admin/report_master.html",
                           master_reports=reports,
                           admin_name=session["user_name"])

@admin_bp.route("/api/report-master/save-all", methods=["POST"])
@admin_required
def api_save_all_master_reports():
    """Bulk-save display_name + category for all reports in ReportClientAccess."""
    data = request.json or {}
    rows = data.get("reports", [])
    saved = 0
    for r in rows:
        path = r.get("report_path", "").strip()
        disp = r.get("display_name", "").strip()
        cat  = r.get("category", "").strip()
        if not path or not disp:
            continue
        is_active = r.get("is_active", True)
        ok = update_report_meta(path, disp, cat, is_active=bool(is_active))
        if ok:
            saved += 1
    log_action(session["user_id"], "BULK_UPDATE_REPORT_META",
               ip=request.remote_addr, extra=f"saved={saved}")
    return jsonify({"success": True, "saved": saved})