import io

from flask import Blueprint, render_template, request, send_file, abort, redirect, url_for
from flask_login import login_required, current_user

from app.models.user import User
from app.services.permissions import require
from app.services.activity_logger import log_action
from app.services import customer_service, reports as reports_service, tag_service
from app.services.jalali import jalali_str_to_gregorian_date

bp = Blueprint("reports", __name__, url_prefix="/reports")


def _parse_customer_filters(args):
    cities = args.getlist("cities")
    tag_ids = [int(t) for t in args.getlist("tag_ids") if t.isdigit()]
    min_amount = float(args["min_amount"]) if args.get("min_amount", "").strip() else None
    max_amount = float(args["max_amount"]) if args.get("max_amount", "").strip() else None
    date_from = date_to = None
    try:
        if args.get("date_from", "").strip():
            date_from = jalali_str_to_gregorian_date(args["date_from"].strip())
        if args.get("date_to", "").strip():
            date_to = jalali_str_to_gregorian_date(args["date_to"].strip())
    except Exception:
        pass

    sort = args.get("sort", "amount_desc")
    mode = args.get("time_mode", "none")
    if mode == "sleeping" and date_from and date_to:
        sort = "range_asc"
    elif mode == "active" and date_from and date_to:
        sort = "range_desc"

    return dict(cities=cities or None, tag_ids=tag_ids or None, min_amount=min_amount,
                max_amount=max_amount, date_from=date_from, date_to=date_to, sort=sort)


def _parse_salesperson_filters(args):
    salesperson_ids = [int(s) for s in args.getlist("salesperson_ids") if s.isdigit()]
    date_from = date_to = None
    try:
        if args.get("date_from", "").strip():
            date_from = jalali_str_to_gregorian_date(args["date_from"].strip())
        if args.get("date_to", "").strip():
            date_to = jalali_str_to_gregorian_date(args["date_to"].strip())
    except Exception:
        pass
    answered_raw = args.get("answered")
    answered = {"1": True, "0": False}.get(answered_raw)
    sort = args.get("sort", "date_desc")
    return dict(salesperson_ids=salesperson_ids or None, date_from=date_from, date_to=date_to,
                answered=answered, sort=sort)


@bp.route("/")
@login_required
@require("reports")
def index():
    return redirect(url_for("reports.customers"))


@bp.route("/customers")
@login_required
@require("reports")
def customers():
    has_filters = len(request.args) > 0
    rows = None
    if has_filters:
        filters = _parse_customer_filters(request.args)
        rows = reports_service.build_customer_report(**filters)
        log_action(current_user, "report", "customer", details={"count": len(rows)})
    return render_template("reports/customers.html", cities=customer_service.distinct_cities(),
                            tag_groups=tag_service.all_tags_grouped(), rows=rows, args=request.args)


@bp.route("/customers/export.<fmt>")
@login_required
@require("reports")
def customers_export(fmt):
    if fmt not in ("xlsx", "pdf"):
        abort(404)
    filters = _parse_customer_filters(request.args)
    rows = reports_service.build_customer_report(**filters)
    buffer = io.BytesIO()
    if fmt == "xlsx":
        reports_service.export_customers_excel(rows, buffer)
        mimetype = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    else:
        reports_service.export_customers_pdf(rows, buffer)
        mimetype = "application/pdf"
    buffer.seek(0)
    log_action(current_user, "export", "customer_report", details={"format": fmt, "count": len(rows)})
    return send_file(buffer, mimetype=mimetype, as_attachment=True, download_name=f"گزارش-مشتریان.{fmt}")


@bp.route("/salespeople")
@login_required
@require("reports")
def salespeople():
    has_filters = len(request.args) > 0
    calls = None
    if has_filters:
        filters = _parse_salesperson_filters(request.args)
        calls = reports_service.build_salesperson_report(**filters)
        log_action(current_user, "report", "salesperson", details={"count": len(calls)})
    return render_template("reports/salespeople.html", salespeople=User.query.order_by(User.full_name).all(),
                            calls=calls, args=request.args)


@bp.route("/salespeople/export.<fmt>")
@login_required
@require("reports")
def salespeople_export(fmt):
    if fmt not in ("xlsx", "pdf"):
        abort(404)
    filters = _parse_salesperson_filters(request.args)
    calls = reports_service.build_salesperson_report(**filters)
    buffer = io.BytesIO()
    if fmt == "xlsx":
        reports_service.export_salespeople_excel(calls, buffer)
        mimetype = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    else:
        reports_service.export_salespeople_pdf(calls, buffer)
        mimetype = "application/pdf"
    buffer.seek(0)
    log_action(current_user, "export", "salesperson_report", details={"format": fmt, "count": len(calls)})
    return send_file(buffer, mimetype=mimetype, as_attachment=True, download_name=f"گزارش-فروشنده‌ها.{fmt}")
