# apps/leave_form_app/api/v1/routes_auth.py
from __future__ import annotations

import os
import json
import sys
import subprocess
from pathlib import Path

from flask import Blueprint, request, jsonify, current_app

from config.db import get_session
from apps.leave_form_app.models import RolePositionMap

auth_bp = Blueprint("leave_api_auth", __name__)

def _get_masterpass() -> str:
    return (os.getenv("LEAVE_APP_MASTERPASS") or "").strip()

def _project_root() -> str:
    return str(Path(__file__).resolve().parents[4])

def _run_aroflo_users_by_email(email: str) -> dict:
    project_root = _project_root()
    cmd = [sys.executable, "-m", "apps.aroflo_connector_app.cli", "users", "by-email", "--email", email, "--raw"]

    env = os.environ.copy()
    env["PYTHONPATH"] = project_root + (":" + env["PYTHONPATH"] if env.get("PYTHONPATH") else "")
    env["PYTHONNOUSERSITE"] = "1"

    current_app.logger.info("[leave_app] aroflo-cli cmd=%s", " ".join(cmd))

    proc = subprocess.run(cmd, cwd=project_root, env=env, capture_output=True, text=True, check=False)
    if proc.returncode != 0:
        raise RuntimeError(f"AroFlo CLI failed rc={proc.returncode} stderr={proc.stderr.strip()[:800]} stdout={proc.stdout.strip()[:800]}")

    out = (proc.stdout or "").strip()
    if not out:
        raise RuntimeError("AroFlo CLI returned empty stdout")

    return json.loads(out)

def _normalize_aroflo_user(payload: dict) -> dict | None:
    data = (payload or {}).get("data") or {}
    match = data.get("match") or {}
    if not match:
        return None

    org = match.get("org") or {}
    userposition = match.get("userposition") or {}

    givennames = (match.get("givennames") or "").strip()
    surname = (match.get("surname") or "").strip()
    full_name = (f"{givennames} {surname}").strip() or (match.get("username") or "").strip()

    return {
        "userid": (match.get("userid") or "").strip(),
        "email": (match.get("email") or "").strip(),
        "mobile": (match.get("mobile") or "").strip(),
        "phone": (match.get("phone") or "").strip(),
        "full_name": full_name,
        "username": (match.get("username") or "").strip(),
        "orgid": (org.get("orgid") or "").strip(),
        "orgname": (org.get("orgname") or "").strip(),
        "positionid": (userposition.get("positionid") or "").strip(),
        "positionname": (userposition.get("positionname") or match.get("position") or "").strip(),
    }

def _resolve_role_from_position(positionid: str, positionname: str) -> str:
    session = get_session()
    try:
        q = session.query(RolePositionMap)
        row = None
        if positionid:
            row = q.filter(RolePositionMap.positionid == positionid).first()
        if not row and positionname:
            row = q.filter(RolePositionMap.positionname == positionname).first()
        if row and row.is_enabled and row.role:
            return row.role
        return "worker"
    finally:
        session.close()

def _normalize_role(role: str) -> str:
    r = (role or "").strip().lower()
    if r in ("worker", "manager", "admin", "superadmin"):
        return r
    if r in ("director",):
        return "admin"
    return "worker"


def _capabilities_for_role(role: str) -> dict:
    r = _normalize_role(role)
    return {
        "can_select_bu_tc": r in ("manager", "admin", "superadmin"),
        "can_approve_team": r in ("manager", "admin", "superadmin"),
        "can_view_team": r in ("manager", "admin", "superadmin"),
        "can_view_all": r in ("admin", "superadmin"),
        "can_push_to_aroflo": r in ("superadmin",),
        "can_assign_roles": r in ("superadmin",),

        # UX helpers
        "is_worker": r == "worker",
        "is_manager": r == "manager",
        "is_admin": r == "admin",
        "is_superadmin": r == "superadmin",
    }



@auth_bp.post("/auth/login")
def auth_login():
    data = request.get_json(silent=True) or {}
    email = (data.get("email") or "").strip().lower()
    password = data.get("password") or ""

    if not email or "@" not in email:
        return jsonify({"status": "error", "message": "Missing/invalid email"}), 400

    masterpass = _get_masterpass()
    if not masterpass:
        return jsonify({"status": "error", "message": "Missing LEAVE_APP_MASTERPASS in env"}), 500

    if password != masterpass:
        return jsonify({"status": "error", "message": "Invalid password"}), 401

    try:
        raw = _run_aroflo_users_by_email(email)
        profile = _normalize_aroflo_user(raw)
        if not profile:
            return jsonify({"status": "error", "message": "User not found in AroFlo"}), 404

        role = _resolve_role_from_position(profile.get("positionid", ""), profile.get("positionname", ""))
        role = _normalize_role(role)
        profile["role"] = role

        return jsonify({
            "status": "ok",
            "user": profile,
            "capabilities": _capabilities_for_role(role),
        })

    except Exception as e:
        current_app.logger.exception("[leave_app] auth_login failed")
        return jsonify({"status": "error", "message": str(e)}), 500
