import json
import logging
import os

import requests

logger = logging.getLogger(__name__)

BASE_URL = os.getenv("TAX_SUGGESTIONS_URL", "http://217.217.249.121:8015")
ENDPOINT = os.getenv("TAX_SUGGESTIONS_ENDPOINT", "/suggestions")
TIMEOUT = int(os.getenv("TAX_SUGGESTIONS_TIMEOUT", "180"))

# Injected by the platform for internal context — must never reach the tax service,
# whose /suggestions handler reads the raw request body as the ERP wrapper.
_INTERNAL_KEYS = {"_tenant_id", "_user_id", "_login", "session_id", "input_type"}


def _build_url() -> str:
    if not BASE_URL:
        raise ValueError("TAX_SUGGESTIONS_URL is not configured")
    return f"{BASE_URL.rstrip('/')}/{ENDPOINT.lstrip('/')}"


def generate_tax_suggestions(input_data: dict):
    if not isinstance(input_data, dict):
        raise ValueError("Tax Suggestions requires the ERP payroll JSON as input")

    payload = {k: v for k, v in input_data.items() if k not in _INTERNAL_KEYS}

    # The platform keeps parsed JSON objects as-is but wraps anything else as
    # {"text": "..."} — so a plain array of employee rows arrives as a string.
    # Unwrap it so the tax service receives the array it expects.
    if set(payload) == {"text"} and isinstance(payload.get("text"), str):
        try:
            payload = json.loads(payload["text"])
        except (ValueError, TypeError):
            raise ValueError(
                "Tax Suggestions requires ERP payroll JSON — either the wrapper "
                '{"Id": 0, "Body": "[...]", "OUId": 0} or a plain array of employee rows.'
            )

    if not payload:
        raise ValueError(
            "Tax Suggestions requires the ERP payroll JSON. Send the full wrapper, "
            'e.g. {"Id": 0, "Body": "[...]", "OUId": 0}'
        )

    response = requests.post(
        _build_url(),
        json=payload,
        timeout=TIMEOUT,
    )

    if not response.ok:
        logger.error(
            "Tax Suggestions service error %d: %s",
            response.status_code,
            response.text,
        )

    response.raise_for_status()

    try:
        return response.json()
    except ValueError:
        return {"result": response.text}
