from urllib.parse import urlparse

import requests

from app.keepedu_http import post_json_comprimido
from app.settings import KEEPEDU_GESTOR_LOGIN_URL
from app.settings import (
    KEEPEDU_API_KEY,
    KEEPEDU_LOGIN_URL,
    KEEPEDU_LOGIN_SCHOOL,
    KEEPEDU_ORIGIN_URL,
    ambiente_local,
)


KEEPEDU_IMPORTAR_TIMEOUT_SECONDS = 30


def _mensagem_resposta(resposta: requests.Response, prefixo: str) -> str:
    """Extrai uma mensagem segura de erro sem registrar credenciais."""
    try:
        dados = resposta.json()
    except ValueError:
        dados = {}

    if isinstance(dados, dict):
        for chave in ("mensagem", "message", "error", "erro"):
            valor = dados.get(chave)
            if isinstance(valor, list):
                itens = [str(item).strip() for item in valor if str(item).strip()]
                if itens:
                    return " | ".join(itens[:3])
            elif valor:
                return str(valor).strip()

    if resposta.status_code in {401, 403}:
        return "E-mail ou senha inválidos."
    return f"{prefixo}: HTTP {resposta.status_code}."


def autenticar_keepedu(email: str, senha: str) -> tuple[bool, str, dict]:
    email = str(email or "").strip()
    senha = str(senha or "").strip()

    if not email or not senha:
        return False, "Informe e-mail e senha.", {}
    if ambiente_local():
        return _autenticar_portal_gestor(email, senha)
    return _autenticar_api(email, senha)


def _autenticar_portal_gestor(email: str, senha: str) -> tuple[bool, str, dict]:
    if not KEEPEDU_GESTOR_LOGIN_URL:
        return False, "Login KeepEdu não configurado.", {}

    sessao = requests.Session()
    cabecalhos = {
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
        "User-Agent": "Mozilla/5.0",
        "Referer": KEEPEDU_GESTOR_LOGIN_URL,
    }

    try:
        # O Portal do Gestor autentica por formulário em /gestor/login. Este é
        # o mesmo contrato usado pelo navegador e não exige escolher `school`.
        sessao.get(
            KEEPEDU_GESTOR_LOGIN_URL,
            headers=cabecalhos,
            timeout=KEEPEDU_IMPORTAR_TIMEOUT_SECONDS,
        )
        resposta = sessao.post(
            KEEPEDU_GESTOR_LOGIN_URL,
            data={"email": email, "senha_login": senha},
            headers=cabecalhos,
            allow_redirects=True,
            timeout=KEEPEDU_IMPORTAR_TIMEOUT_SECONDS,
        )
    except requests.RequestException as exc:
        return False, f"Não foi possível conectar ao login KeepEdu: {exc}", {}

    url_final = urlparse(str(resposta.url or "")).path.rstrip("/").lower()
    rota_login = urlparse(KEEPEDU_GESTOR_LOGIN_URL).path.rstrip("/").lower()
    if resposta.status_code >= 400 or url_final == rota_login:
        return False, _mensagem_resposta(resposta, "Login KeepEdu"), {}

    return True, "", {
        # O Portal do Gestor mantém a identidade na sessão HTTP. Para a sessão
        # do OMRCheck, o e-mail é um identificador local estável.
        "id": email.lower(),
        "name": email.split("@", 1)[0],
        "email": email,
        "origem": "keepedu_portal",
    }


def _autenticar_api(email: str, senha: str) -> tuple[bool, str, dict]:
    """Mantém o contrato de autenticação já usado em produção."""
    if not KEEPEDU_LOGIN_URL:
        return False, "Login KeepEdu não configurado.", {}

    try:
        sessao = requests.Session()
        sessao.get(
            KEEPEDU_GESTOR_LOGIN_URL,
            headers={"User-Agent": "Mozilla/5.0", "Apikey": KEEPEDU_API_KEY},
            timeout=KEEPEDU_IMPORTAR_TIMEOUT_SECONDS,
        )
        resposta = post_json_comprimido(
            KEEPEDU_LOGIN_URL,
            {"email": email, "senha": senha, "school": KEEPEDU_LOGIN_SCHOOL},
            headers={
                "Accept": "application/json",
                "Content-Type": "application/json",
                "User-Agent": "Mozilla/5.0",
                "Referer": KEEPEDU_GESTOR_LOGIN_URL,
                "Origin": KEEPEDU_ORIGIN_URL,
                "Apikey": KEEPEDU_API_KEY,
            },
            allow_redirects=True,
            timeout=KEEPEDU_IMPORTAR_TIMEOUT_SECONDS,
            client=sessao,
        )
    except requests.RequestException as exc:
        return False, f"Não foi possível conectar ao login KeepEdu: {exc}", {}

    if resposta.status_code not in {200, 201, 302}:
        return False, _mensagem_resposta(resposta, "Login KeepEdu"), {}

    try:
        dados = resposta.json()
    except ValueError:
        dados = {}
    if not isinstance(dados, dict) or dados.get("success") is False:
        return False, _mensagem_resposta(resposta, "Login KeepEdu"), {}

    auth = dados.get("auth", {}) if isinstance(dados.get("auth"), dict) else {}
    usuario = auth.get("user", {}) if isinstance(auth.get("user"), dict) else {}
    school = (
        auth.get("school")
        or dados.get("school")
        or usuario.get("school")
        or usuario.get("school_slug")
        or KEEPEDU_LOGIN_SCHOOL
    )
    return True, "", {
        "id": usuario.get("id"),
        "name": usuario.get("name"),
        "email": usuario.get("email"),
        "school": str(school or "").strip().lower(),
        "origem": "keepedu",
    }
