"""A/B 테스트: Gemini vs GPT Image 포토 모델 비교.

photo 타입 프롬프트 3개로 각 모델의 성공률, 생성 시간, 파일 크기, 해상도를 측정한다.

실행:
    python3 ab_test_photo_models.py
"""

import json
import logging
import sys
import time
from pathlib import Path

# image_router.py가 있는 디렉토리를 sys.path에 추가
_AI_IMAGE_GEN_DIR = Path("/home/jay/workspace/tools/ai-image-gen")
if str(_AI_IMAGE_GEN_DIR) not in sys.path:
    sys.path.insert(0, str(_AI_IMAGE_GEN_DIR))

import image_router as _ir  # pyright: ignore[reportMissingImports]  # noqa: E402

_generate_gemini = _ir._generate_gemini  # pyright: ignore[reportAttributeAccessIssue]
_generate_gpt = _ir._generate_gpt  # pyright: ignore[reportAttributeAccessIssue]

# ─────────────────────────────────────────────────────────────────────────────
# 로거 설정
# ─────────────────────────────────────────────────────────────────────────────

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(name)s — %(message)s",
    datefmt="%H:%M:%S",
)
log = logging.getLogger("ab_test")

# ─────────────────────────────────────────────────────────────────────────────
# 상수
# ─────────────────────────────────────────────────────────────────────────────

TEST_DATE = "2026-04-11"
OUTPUT_DIR = Path("/home/jay/workspace/tools/ai-image-gen/output/ab_test")
RESULTS_JSON = OUTPUT_DIR / "results.json"
INTER_CALL_DELAY_SEC = 2  # 각 모델 호출 간 대기 시간 (안전 마진)

PROMPTS = [
    {
        "id": "P1",
        "text": (
            "Professional insurance office interior, modern Korean style, "
            "natural lighting, clean desk with laptop"
        ),
    },
    {
        "id": "P2",
        "text": (
            "Happy Korean family reviewing insurance documents with financial advisor, "
            "warm indoor setting"
        ),
    },
    {
        "id": "P3",
        "text": (
            "Abstract visualization of insurance protection concept, "
            "shield, umbrella, minimalist style"
        ),
    },
]


# ─────────────────────────────────────────────────────────────────────────────
# 헬퍼 함수
# ─────────────────────────────────────────────────────────────────────────────


def _get_resolution(image_path: Path) -> str:
    """PIL로 이미지 해상도를 'WxH' 형식으로 반환한다.

    PIL import 실패 또는 파일 읽기 실패 시 'unknown'을 반환한다.
    """
    try:
        from PIL import Image

        with Image.open(image_path) as img:
            w, h = img.size
            return f"{w}x{h}"
    except Exception as exc:
        log.warning("해상도 확인 실패 (%s): %s", image_path.name, exc)
        return "unknown"


def _run_single(
    model_name: str,
    generate_fn,
    prompt_text: str,
    output_path: Path,
) -> dict:
    """단일 모델 호출을 실행하고 측정 결과 dict를 반환한다.

    Args:
        model_name: 로그용 모델 식별자 ("gemini" 또는 "gpt")
        generate_fn: _generate_gemini 또는 _generate_gpt
        prompt_text: 이미지 생성 프롬프트
        output_path: 결과 이미지 저장 경로

    Returns:
        측정 결과 dict
    """
    log.info("[%s] 호출 시작 → %s", model_name.upper(), output_path.name)
    result: dict = {
        "success": False,
        "time_sec": None,
        "file_size": None,
        "resolution": None,
        "path": None,
        "error": None,
    }

    t0 = time.monotonic()
    try:
        output_path.parent.mkdir(parents=True, exist_ok=True)
        success = generate_fn(prompt_text, output_path)
        elapsed = round(time.monotonic() - t0, 2)
        result["time_sec"] = elapsed

        if success:
            actual_path = (
                output_path.with_suffix(".jpg")
                if not output_path.exists() and output_path.with_suffix(".jpg").exists()
                else output_path
            )
            result["success"] = True
            result["file_size"] = actual_path.stat().st_size
            result["resolution"] = _get_resolution(actual_path)
            result["path"] = str(actual_path)
            log.info(
                "[%s] 성공 | %.2fs | %d bytes | %s",
                model_name.upper(),
                elapsed,
                result["file_size"],
                result["resolution"],
            )
        else:
            result["error"] = "생성 함수가 False를 반환함"
            log.warning("[%s] 실패 (False 반환) | %.2fs", model_name.upper(), elapsed)

    except Exception as exc:
        elapsed = round(time.monotonic() - t0, 2)
        result["time_sec"] = elapsed
        result["error"] = f"{type(exc).__name__}: {exc}"
        log.error("[%s] 예외 발생: %s", model_name.upper(), result["error"])

    return result


# ─────────────────────────────────────────────────────────────────────────────
# 메인 테스트 로직
# ─────────────────────────────────────────────────────────────────────────────


def run_ab_test() -> dict:
    """A/B 테스트를 실행하고 결과 dict를 반환한다."""
    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
    log.info("=== A/B 테스트 시작: Gemini vs GPT Image (%s) ===", TEST_DATE)

    results = []

    for prompt_entry in PROMPTS:
        pid = prompt_entry["id"]
        prompt_text = prompt_entry["text"]
        log.info("--- [%s] 프롬프트: %s...", pid, prompt_text[:60])

        gemini_out = OUTPUT_DIR / f"gemini_{pid.lower()}.png"
        gpt_out = OUTPUT_DIR / f"gpt_{pid.lower()}.png"

        # Gemini 호출
        gemini_result = _run_single("gemini", _generate_gemini, prompt_text, gemini_out)
        log.info("다음 호출까지 %d초 대기...", INTER_CALL_DELAY_SEC)
        time.sleep(INTER_CALL_DELAY_SEC)

        # GPT 호출
        gpt_result = _run_single("gpt", _generate_gpt, prompt_text, gpt_out)

        # 프롬프트 간 대기 (마지막 프롬프트 제외)
        if prompt_entry is not PROMPTS[-1]:
            log.info("다음 프롬프트까지 %d초 대기...", INTER_CALL_DELAY_SEC)
            time.sleep(INTER_CALL_DELAY_SEC)

        results.append(
            {
                "prompt_id": pid,
                "prompt": prompt_text,
                "gemini": gemini_result,
                "gpt": gpt_result,
            }
        )

    # 요약 통계 계산
    gemini_successes = [r for r in results if r["gemini"]["success"]]
    gpt_successes = [r for r in results if r["gpt"]["success"]]

    gemini_times = [r["gemini"]["time_sec"] for r in results if r["gemini"]["time_sec"] is not None]
    gpt_times = [r["gpt"]["time_sec"] for r in results if r["gpt"]["time_sec"] is not None]

    gemini_avg_time = round(sum(gemini_times) / len(gemini_times), 2) if gemini_times else None
    gpt_avg_time = round(sum(gpt_times) / len(gpt_times), 2) if gpt_times else None

    total = len(PROMPTS)
    summary = {
        "gemini_success_rate": f"{len(gemini_successes)}/{total}",
        "gpt_success_rate": f"{len(gpt_successes)}/{total}",
        "gemini_avg_time": gemini_avg_time,
        "gpt_avg_time": gpt_avg_time,
    }

    output = {
        "test_date": TEST_DATE,
        "results": results,
        "summary": summary,
    }

    # JSON 저장
    RESULTS_JSON.write_text(json.dumps(output, ensure_ascii=False, indent=2), encoding="utf-8")
    log.info("=== 테스트 완료. 결과 저장: %s ===", RESULTS_JSON)
    log.info(
        "요약 | Gemini: %s | GPT: %s | Gemini 평균시간: %ss | GPT 평균시간: %ss",
        summary["gemini_success_rate"],
        summary["gpt_success_rate"],
        summary["gemini_avg_time"],
        summary["gpt_avg_time"],
    )

    return output


# ─────────────────────────────────────────────────────────────────────────────
# 진입점
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    run_ab_test()
