"""Upload generated token JSON files to a remote server endpoint."""

from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path
import httpx


PURPOSE_FOLDERS = {
    "like100": "100like",
    "like200": "200like",
    "free": "100like",
}


@dataclass(frozen=True)
class UploadResult:
    enabled: bool
    success: bool
    remote_path: str
    reason: str = ""
    status: str = ""
    folder: str = ""
    filename: str = ""
    saved_to: str = ""
    tokens: int | None = None
    size: int | None = None


def remote_folder_for_purpose(purpose: str) -> str:
    return PURPOSE_FOLDERS.get(purpose.lower(), purpose.lower())


def remote_filename_for_server(server: str) -> str:
    return f"token_{server.lower()}.json"


def remote_path_for(server: str, purpose: str) -> str:
    return f"{remote_folder_for_purpose(purpose)}/{remote_filename_for_server(server)}"


async def upload_token_file(
    *,
    base_url: str,
    file_path: Path,
    server: str,
    purpose: str,
    timeout: float,
    auth_token: str = "",
) -> UploadResult:
    remote_path = remote_path_for(server, purpose)
    if not base_url:
        return UploadResult(enabled=False, success=False, remote_path=remote_path, reason="missing upload url")

    url = f"{base_url.rstrip('/')}/{remote_path}"
    headers = {}
    if auth_token:
        headers["Authorization"] = f"Bearer {auth_token}"

    try:
        async with httpx.AsyncClient(timeout=timeout) as client:
            with file_path.open("rb") as handle:
                response = await client.post(
                    url,
                    files={"file": (remote_filename_for_server(server), handle, "application/json")},
                    data={
                        "server": server,
                        "purpose": purpose,
                        "folder": remote_folder_for_purpose(purpose),
                        "filename": remote_filename_for_server(server),
                    },
                    headers=headers,
                )
        payload = {}
        try:
            parsed = response.json()
            if isinstance(parsed, dict):
                payload = parsed
        except ValueError:
            payload = {}

        if 200 <= response.status_code < 300 and payload.get("status") == "success":
            return UploadResult(
                enabled=True,
                success=True,
                remote_path=remote_path,
                status=str(payload.get("status", "")),
                folder=str(payload.get("folder", "")),
                filename=str(payload.get("filename", "")),
                saved_to=str(payload.get("saved_to", "")),
                tokens=int(payload["tokens"]) if payload.get("tokens") is not None else None,
                size=int(payload["size"]) if payload.get("size") is not None else None,
            )
        if 200 <= response.status_code < 300:
            return UploadResult(
                enabled=True,
                success=False,
                remote_path=remote_path,
                reason=str(payload.get("detail") or payload.get("message") or "upload status not success"),
                status=str(payload.get("status", "")),
            )
        return UploadResult(
            enabled=True,
            success=False,
            remote_path=remote_path,
            reason=str(payload.get("detail") or payload.get("message") or f"HTTP {response.status_code}"),
            status=str(payload.get("status", "")),
        )
    except httpx.TimeoutException:
        return UploadResult(enabled=True, success=False, remote_path=remote_path, reason="upload timeout")
    except httpx.HTTPError:
        return UploadResult(enabled=True, success=False, remote_path=remote_path, reason="upload request failed")
    except OSError as exc:
        return UploadResult(enabled=True, success=False, remote_path=remote_path, reason=str(exc))
