#!/usr/bin/env python3
from __future__ import annotations

import asyncio
import base64
import logging
import os
from typing import Any

import aiohttp

logger = logging.getLogger(__name__)

GEMINI_API_KEY = "sk-8i7uYE0RtnQwDImV8a5f7014DcAb46F6BcEb72Df92218aC8"
GEMINI_API_URL = "https://api.laozhang.ai/v1beta/models"
GEMINI_MODEL = "gemini-3.1-flash-image-preview"
GEMINI_IMAGE_SIZE = "4K"
GEMINI_MAX_RETRIES = 3

DEFAULT_PROMPT = (
    "提取印花图案，去褶皱并补齐缺失区域，生成完整清晰的平面图。"
    "严格保持原图元素位置、颜色和细节，不要改风格。"
)


class GeminiExtractStableService:
    def image_to_base64(self, image_path: str) -> str | None:
        try:
            if not os.path.exists(image_path):
                logger.error("文件不存在: %s", image_path)
                return None
            with open(image_path, "rb") as f:
                return base64.b64encode(f.read()).decode("utf-8")
        except Exception as e:
            logger.error("Base64转换失败: %s", e)
            return None

    async def extract_pattern(
        self,
        input_path: str,
        output_path: str,
        custom_prompt: str | None = None,
        aspect_ratio: str = "1:1",
    ) -> tuple[bool, str, dict[str, Any]]:
        img64 = self.image_to_base64(input_path)
        if not img64:
            return False, "图片编码失败", {}

        prompt = custom_prompt or DEFAULT_PROMPT
        api_url = f"{GEMINI_API_URL}/{GEMINI_MODEL}:generateContent"
        valid_ratios = {"1:1", "9:16", "16:9", "3:4", "4:3", "3:2", "2:3", "5:4", "4:5"}
        image_config: dict[str, Any] = {"imageSize": GEMINI_IMAGE_SIZE}
        if aspect_ratio in valid_ratios:
            image_config["aspectRatio"] = aspect_ratio

        headers = {
            "Authorization": f"Bearer {GEMINI_API_KEY}",
            "Content-Type": "application/json",
        }
        payload = {
            "contents": [
                {
                    "parts": [
                        {"text": prompt},
                    ]
                }
            ],
            "generationConfig": {
                "responseModalities": ["IMAGE"],
                "imageConfig": image_config,
            },
        }

        logger.info("[稳定作图] model=%s ratio=%s size=%s", GEMINI_MODEL, image_config.get("aspectRatio", "1:1"), GEMINI_IMAGE_SIZE)
        timeout = aiohttp.ClientTimeout(total=180, connect=30)
        for i in range(1, GEMINI_MAX_RETRIES + 1):
            try:
                logger.info("[稳定作图] 请求中 第%s/%s次", i, GEMINI_MAX_RETRIES)
                async with aiohttp.ClientSession(timeout=timeout) as session:
                    async with session.post(api_url, headers=headers, json=payload) as resp:
                        txt = await resp.text()
                        if resp.status != 200:
                            logger.error("[稳定作图] 请求失败 status=%s body=%s", resp.status, txt[:240])
                            if i < GEMINI_MAX_RETRIES:
                                await asyncio.sleep(i)
                                continue
                            return False, f"API失败:{resp.status}", {}
                        result = await resp.json()

                try:
                    parts = result["candidates"][0]["content"]["parts"]
                    b64 = ""
                    for p in parts:
                        if "inlineData" in p and isinstance(p["inlineData"], dict):
                            b64 = str(p["inlineData"].get("data", "") or "")
                            if b64:
                                break
                    if not b64:
                        logger.error("[稳定作图] 未找到 inlineData")
                        return False, "未找到图片数据", {}
                    image_data = base64.b64decode(b64)
                except Exception as e:
                    logger.error("[稳定作图] 解析返回失败: %s", e)
                    return False, f"解析失败:{e}", {}

                out_dir = os.path.dirname(output_path)
                if out_dir:
                    os.makedirs(out_dir, exist_ok=True)
                with open(output_path, "wb") as f:
                    f.write(image_data)
                logger.info("[稳定作图] 输出成功: %s", output_path)
                return True, "ok", {"output_path": output_path, "file_size": len(image_data), "api_used": "gemini_stable"}
            except Exception as e:
                logger.error("[稳定作图] 异常: %s", e)
                if i < GEMINI_MAX_RETRIES:
                    await asyncio.sleep(i)
                    continue
                return False, f"异常:{e}", {}
        return False, "未知失败", {}

    async def cleanup(self) -> None:
        return None
