"""Publish agent run logs: HTML visualize → OSS upload → MySQL record."""

from __future__ import annotations

import logging
from pathlib import Path
from typing import TYPE_CHECKING

from supply_agent.logging.logger import slugify_agent_name
from supply_agent.logging.visualize import generate_visualization
from supply_infra.config import get_infra_settings
from supply_infra.db.repositories.oss_log_repo import OssLogRepository
from supply_infra.db.session import get_session
from supply_infra.oss.client import OssClient

if TYPE_CHECKING:
    from supply_agent.logging.logger import AgentLogger

_log = logging.getLogger("supply_infra.agent_logging.publish")


def publish_run_artifacts_to_oss(agent_logger: AgentLogger) -> str | None:
    """
    After a run finishes: generate HTML, upload .log/.jsonl/.html to OSS,
    and insert a row into ``oss_logs``.

    Returns the public HTML URL, or None if skipped / failed.
    Failures are logged and do not raise (so agent runs are not broken).
    """
    settings = get_infra_settings()
    if not settings.log_oss_upload_enabled:
        return None
    if not settings.aliyun_oss_access_key_id or not settings.aliyun_oss_access_key_secret:
        _log.debug("OSS credentials missing; skip log publish")
        return None

    log_file = agent_logger.log_file
    jsonl_file = agent_logger.jsonl_file
    if not log_file or not log_file.exists():
        _log.warning("No log file to publish")
        return None

    try:
        source = jsonl_file if jsonl_file and jsonl_file.exists() else log_file
        html_path = generate_visualization(source)

        agent_slug = slugify_agent_name(agent_logger.agent_name) or "agent"
        log_name = html_path.stem

        client = OssClient(settings)
        files = [p for p in (log_file, jsonl_file, html_path) if p and Path(p).exists()]
        html_url: str | None = None

        for path in files:
            key = client.object_key(agent_slug, Path(path).name)
            url = client.upload_file(path, key)
            if Path(path).suffix.lower() == ".html":
                html_url = url
            _log.info("Uploaded %s → %s", path.name, url)

        if not html_url:
            raise RuntimeError("HTML was not uploaded")

        with get_session() as session:
            OssLogRepository(session).create(
                log_name=log_name,
                agent_name=agent_logger.agent_name or agent_slug,
                oss_path=html_url,
            )

        _log.info("oss_logs saved: log_name=%s url=%s", log_name, html_url)
        print(f"[publish] 可视化已上传: {html_url}")
        return html_url
    except Exception:
        _log.exception("Failed to publish run artifacts")
        print("[publish] 日志上传/入库失败，详见日志；不影响本次 Agent 结果")
        return None
