from __future__ import annotations

import json
import os
import urllib.request
from urllib.error import HTTPError

from flask import Blueprint, request, jsonify, session

# IMPORTANT: Do NOT call Playwright in this app (Apache/mod_wsgi).
# Proxy to ui_automation_worker instead.

ui_session_bp = Blueprint("leave_ui_session", __name__)


def _get_tenant_id(data: dict | None = None) -> str:
    data = data or {}
    tenant_id = (data.get("tenant_id") or data.get("tenant-id") or "").strip()
    if tenant_id:
        session["tenant_id"] = tenant_id
        return tenant_id
    return (session.get("tenant_id") or "<default>").strip()


def _worker_url(path: str) -> str:
    base = (os.getenv("AROFLO_UI_WORKER_URL") or "http://127.0.0.1:5010").rstrip("/")
    return f"{base}{path}"


def _upload_dir() -> str:
    return os.getenv("LEAVE_APP_UPLOAD_DIR") or "/var/www/html/flask_server/tmp/leave_app_uploads"


@ui_session_bp.get("/ui/session/status")
def ui_session_status():
    tenant_id = _get_tenant_id(request.args)
    req = urllib.request.Request(
        _worker_url("/ui/session/status") + (f"?tenant_id={tenant_id}" if tenant_id else ""),
        method="GET",
    )
    try:
        with urllib.request.urlopen(req, timeout=60) as resp:
            body = resp.read().decode("utf-8", "replace")
            return jsonify(json.loads(body)), resp.status
    except HTTPError as e:
        try:
            body = e.read().decode("utf-8", "replace")
            return jsonify(json.loads(body)), e.code
        except Exception:
            return jsonify({"status": "error", "message": "Worker error"}), e.code


@ui_session_bp.post("/ui/session/connect")
def ui_session_connect():
    data = request.get_json(silent=True) or {}
    tenant_id = _get_tenant_id(data)
    payload = {"tenant_id": tenant_id}
    req = urllib.request.Request(
        _worker_url("/ui/session/connect"),
        data=json.dumps(payload).encode("utf-8"),
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=120) as resp:
            body = resp.read().decode("utf-8", "replace")
            return jsonify(json.loads(body)), resp.status
    except HTTPError as e:
        try:
            body = e.read().decode("utf-8", "replace")
            return jsonify(json.loads(body)), e.code
        except Exception:
            return jsonify({"status": "error", "message": "Worker error"}), e.code


@ui_session_bp.post("/ui/session/mfa")
def ui_session_mfa():
    data = request.get_json(silent=True) or {}
    tenant_id = _get_tenant_id(data)
    code = (data.get("code") or "").strip()
    if not code:
        return jsonify({"status": "error", "message": "Missing MFA code"}), 400
    payload = {"tenant_id": tenant_id, "code": code}
    req = urllib.request.Request(
        _worker_url("/ui/session/mfa"),
        data=json.dumps(payload).encode("utf-8"),
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=120) as resp:
            body = resp.read().decode("utf-8", "replace")
            return jsonify(json.loads(body)), resp.status
    except HTTPError as e:
        try:
            body = e.read().decode("utf-8", "replace")
            return jsonify(json.loads(body)), e.code
        except Exception:
            return jsonify({"status": "error", "message": "Worker error"}), e.code


@ui_session_bp.post("/ui/session/close")
def ui_session_close():
    data = request.get_json(silent=True) or {}
    tenant_id = _get_tenant_id(data)
    payload = {"tenant_id": tenant_id}
    req = urllib.request.Request(
        _worker_url("/ui/session/close"),
        data=json.dumps(payload).encode("utf-8"),
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=120) as resp:
            body = resp.read().decode("utf-8", "replace")
            return jsonify(json.loads(body)), resp.status
    except HTTPError as e:
        try:
            body = e.read().decode("utf-8", "replace")
            return jsonify(json.loads(body)), e.code
        except Exception:
            return jsonify({"status": "error", "message": "Worker error"}), e.code


@ui_session_bp.post("/ui/overheads/refresh")
def ui_overheads_refresh():
    data = request.get_json(silent=True) or {}
    tenant_id = _get_tenant_id(data)
    payload = {"tenant_id": tenant_id}
    req = urllib.request.Request(
        _worker_url("/ui/overheads/refresh"),
        data=json.dumps(payload).encode("utf-8"),
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=120) as resp:
            body = resp.read().decode("utf-8", "replace")
            return jsonify(json.loads(body)), resp.status
    except HTTPError as e:
        try:
            body = e.read().decode("utf-8", "replace")
            return jsonify(json.loads(body)), e.code
        except Exception:
            return jsonify({"status": "error", "message": "Worker error"}), e.code


@ui_session_bp.post("/ui/timesheets/create")
def ui_timesheets_create():
    data = request.get_json(silent=True) or {}
    tenant_id = _get_tenant_id(data)
    payload = dict(data or {})
    payload["tenant_id"] = tenant_id
    req = urllib.request.Request(
        _worker_url("/ui/timesheets/create"),
        data=json.dumps(payload).encode("utf-8"),
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=180) as resp:
            body = resp.read().decode("utf-8", "replace")
            return jsonify(json.loads(body)), resp.status
    except HTTPError as e:
        try:
            body = e.read().decode("utf-8", "replace")
            return jsonify(json.loads(body)), e.code
        except Exception:
            return jsonify({"status": "error", "message": "Worker error"}), e.code


@ui_session_bp.post("/ui/users/upload-docs")
def ui_users_upload_docs():
    data = request.get_json(silent=True) or {}
    tenant_id = _get_tenant_id(data)
    payload = dict(data or {})
    payload["tenant_id"] = tenant_id
    docs = payload.get("docs") or []
    if not isinstance(docs, list) or not docs:
        return jsonify({"status": "error", "message": "docs is required"}), 400

    upload_root = _upload_dir()
    for item in docs:
        if not isinstance(item, dict):
            return jsonify({"status": "error", "message": "docs items must be objects"}), 400
        path = (item.get("file") or "").strip()
        if not path:
            return jsonify({"status": "error", "message": "doc missing file"}), 400
        if not path.startswith(upload_root + "/"):
            return jsonify({"status": "error", "message": "doc file must be uploaded via attachments/upload-temp"}), 400
        if not os.path.isfile(path):
            return jsonify({"status": "error", "message": f"doc file not found: {path}"}), 400

    req = urllib.request.Request(
        _worker_url("/ui/users/upload-docs"),
        data=json.dumps(payload).encode("utf-8"),
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=180) as resp:
            body = resp.read().decode("utf-8", "replace")
            return jsonify(json.loads(body)), resp.status
    except HTTPError as e:
        try:
            body = e.read().decode("utf-8", "replace")
            return jsonify(json.loads(body)), e.code
        except Exception:
            return jsonify({"status": "error", "message": "Worker error"}), e.code
