import dataiku
from flask import Blueprint, jsonify, request

from backend.services.analytics import AnalyticsService
from backend.utils.logger_utils import log_http_request
from backend.utils.logging_utils import get_logger
from backend.utils.client_utils import current_request_login
from backend.utils.permissions_utils import has_project_write_access

logger = get_logger(__name__)
dashboard_bp = Blueprint("dashboard", __name__, url_prefix="/dashboard")


@dashboard_bp.route("/tiles", methods=["GET"])
@log_http_request
def tiles():
    start = request.args.get("from")
    end = request.args.get("to")
    agent_type = request.args.get("agentType")
    owner_id = request.args.get("ownerId")
    login = current_request_login() or ""
    # po_login = current_project_owner_login() or ""
    # is_po = bool(login and po_login and login == po_login)
    is_admin = has_project_write_access(dataiku.default_project_key(), login)

    analytics_svc = AnalyticsService(login)
    payload = analytics_svc.dashboard_tiles(
        start, end, is_project_admin=is_admin, agent_type=agent_type, owner_id=owner_id
    )
    if is_admin:
        payload["scope"] = {"agentType": (agent_type or "all"), "ownerId": owner_id}
    return jsonify(payload), 200


@dashboard_bp.route("/usage", methods=["GET"])
@log_http_request
def usage():
    start = request.args.get("from")
    end = request.args.get("to")
    bucket = (request.args.get("bucket") or "week").lower()
    agent_id = request.args.get("agentId")
    agent_type = request.args.get("agentType")
    owner_id = request.args.get("ownerId")
    login = current_request_login() or ""
    # po_login = current_project_owner_login() or ""
    # is_po = bool(login and po_login and login == po_login)
    is_admin = has_project_write_access(dataiku.default_project_key(), login)
    analytics_svc = AnalyticsService(login)
    series = analytics_svc.dashboard_usage(
        start, end, bucket, agent_id, is_project_admin=is_admin, agent_type=agent_type, owner_id=owner_id
    )
    avg_usage = 0
    if series:
        total = sum(point.get("count", 0) for point in series)
        periods = len(series)
        # Round to the nearest integer to match the example payload
        avg_usage = int(round(total / periods))

    payload = {"bucket": bucket, "avgUsage": avg_usage, "series": series}
    if is_admin:
        payload["scope"] = {"agentType": (agent_type or "all"), "ownerId": owner_id}
    return jsonify(payload), 200


@dashboard_bp.route("/feedback", methods=["GET"])
@log_http_request
def feedback():
    start = request.args.get("from")
    end = request.args.get("to")
    agent_id = request.args.get("agentId")
    agent_type = request.args.get("agentType")
    owner_id = request.args.get("ownerId")

    login = current_request_login() or ""
    # po_login = current_project_owner_login() or ""
    # is_po = bool(login and po_login and login == po_login)
    is_admin = has_project_write_access(dataiku.default_project_key(), login)
    analytics_svc = AnalyticsService(login)
    payload = analytics_svc.dashboard_feedback(
        start, end, agent_id, is_project_admin=is_admin, agent_type=agent_type, owner_id=owner_id
    )
    if is_admin:
        payload["scope"] = {"agentType": (agent_type or "all"), "ownerId": owner_id}
    return jsonify(payload), 200


@dashboard_bp.route("/activity", methods=["GET"])
@log_http_request
def activity():
    start = request.args.get("from")
    end = request.args.get("to")
    agent_id = request.args.get("agentId")
    limit = int(request.args.get("limit", 50))
    offset = int(request.args.get("offset", 0))
    q = request.args.get("q")
    sort_by = request.args.get("sortBy")
    sort_dir = request.args.get("sortDir")
    group_by = request.args.get("groupBy")
    agent_type = request.args.get("agentType")
    owner_id = request.args.get("ownerId")

    login = current_request_login() or ""
    # po_login = current_project_owner_login() or ""
    # is_po = bool(login and po_login and login == po_login)
    is_admin = has_project_write_access(dataiku.default_project_key(), login)
    logger.info(f"Activity request by user '{login}' (is admin: {is_admin})'")
    analytics_svc = AnalyticsService(login)
    payload = analytics_svc.dashboard_activity(
        start,
        end,
        agent_id,
        limit,
        offset,
        q=q,
        sort_by=sort_by,
        sort_dir=sort_dir,
        group_by=group_by,
        is_project_admin=is_admin,
        agent_type=agent_type,
        owner_id=owner_id,
    )
    if is_admin:
        payload["scope"] = {"agentType": (agent_type or "all"), "ownerId": owner_id, "groupBy": group_by}
    return jsonify(payload), 200


@dashboard_bp.route("/my-agents", methods=["GET"])
@log_http_request
def my_agents():
    owner_id = request.args.get("ownerId")
    login = current_request_login() or ""
    # po_login = current_project_owner_login() or ""
    # is_po = bool(login and po_login and login == po_login)
    is_admin = has_project_write_access(dataiku.default_project_key(), login)
    analytics = AnalyticsService(login)
    return jsonify({"agents": analytics.my_agents_minimal(is_project_admin=is_admin, owner_id=owner_id)}), 200


@dashboard_bp.route("/active-users", methods=["GET"])
@log_http_request
def active_users():
    """
    COUNT(DISTINCT user_id) per bucket (day/week/month) among messages where an owned agent was actually invoked.
    """
    start = request.args.get("from")
    end = request.args.get("to")
    bucket = (request.args.get("bucket") or "week").lower()
    agent_id = request.args.get("agentId")
    agent_type = request.args.get("agentType")
    owner_id = request.args.get("ownerId")
    login = current_request_login() or ""
    # po_login = current_project_owner_login() or ""
    # is_po = bool(login and po_login and login == po_login)
    is_admin = has_project_write_access(dataiku.default_project_key(), login)
    analytics_svc = AnalyticsService(login)
    series = analytics_svc.dashboard_active_users(
        start, end, bucket, agent_id, is_project_admin=is_admin, agent_type=agent_type, owner_id=owner_id
    )
    payload = {"bucket": bucket, "series": series}
    if is_admin:
        payload["scope"] = {"agentType": (agent_type or "all"), "ownerId": owner_id}
    return jsonify(payload), 200
