"""BFL FLUX 本地封装 — 异步生图（提交 + 轮询）。

环境变量：
  BFL_API_KEY   必填，请求头 x-key
  BFL_API_BASE  可选，默认 https://api.bfl.ai/v1（全球端点；也可用 api.eu.bfl.ai/v1 等）

接口：
  GET  /health
  POST /submit  提交生成；body.model 为端点路径段，如 flux-2-pro-preview
  POST /query   轮询；polling_url、request_id 来自提交响应

文档: https://docs.bfl.ai/quick_start/generating_images
"""

from __future__ import annotations

import argparse
from typing import Any

import uvicorn
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field

from bfl_client import poll_result, submit_generation

app = FastAPI(title="BFL FLUX API Proxy")


class SubmitRequest(BaseModel):
    model: str = Field(
        ...,
        description="模型端点路径段，如 flux-2-pro-preview、flux-2-max、flux-dev（对应 /v1/{model}）",
    )
    prompt: str = Field(..., description="文生图提示词")
    width: int | None = Field(default=None, description="输出宽度（像素）")
    height: int | None = Field(default=None, description="输出高度（像素）")
    parameters: dict[str, Any] | None = Field(
        default=None,
        description="合并进请求体的额外字段（官方各模型可选参数）",
    )


class QueryRequest(BaseModel):
    polling_url: str = Field(..., description="提交响应中的 polling_url，须原样使用")
    request_id: str = Field(..., description="提交响应中的 id")


@app.get("/health")
def health() -> dict[str, str]:
    return {"status": "ok"}


@app.post("/submit")
def submit(req: SubmitRequest) -> dict[str, Any]:
    try:
        return submit_generation(
            model=req.model,
            prompt=req.prompt,
            width=req.width,
            height=req.height,
            parameters=req.parameters,
        )
    except ValueError as e:
        raise HTTPException(status_code=503, detail=str(e)) from e
    except RuntimeError as e:
        raise HTTPException(status_code=502, detail=str(e)) from e
    except Exception as e:
        raise HTTPException(status_code=502, detail=str(e)) from e


@app.post("/query")
def query(req: QueryRequest) -> dict[str, Any]:
    try:
        return poll_result(polling_url=req.polling_url, request_id=req.request_id)
    except ValueError as e:
        raise HTTPException(status_code=503, detail=str(e)) from e
    except RuntimeError as e:
        raise HTTPException(status_code=502, detail=str(e)) from e
    except Exception as e:
        raise HTTPException(status_code=502, detail=str(e)) from e


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--port", type=int, default=8001)
    args = parser.parse_args()
    uvicorn.run(app, host="0.0.0.0", port=args.port)
