import random
import socket
import uvicorn
from fastapi import FastAPI, Query, Body
from pydantic import BaseModel
from typing import List, Optional
import asyncio
from concurrent.futures import ThreadPoolExecutor
from modules.image_processor2 import ImageProcessor

# 포트 범위 설정
PORT_RANGE = (7000, 7000)

# 사용 가능한 포트 찾기
def find_free_port():
    for _ in range(20):
        port = random.randint(*PORT_RANGE)
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            try:
                s.bind(("127.0.0.1", port))
                return port
            except OSError:
                continue
    raise RuntimeError("사용 가능한 포트를 찾을 수 없습니다.")

# 요청 모델 정의
class ImageRequest(BaseModel):
    local_image_path: str
    file_prefix: Optional[str] = ""
    use_inpainting: Optional[bool] = False
    toggle_states: Optional[dict] = None
    unwanted_texts: Optional[dict] = None
    watermark_text: Optional[str] = None
    watermark_opacity: Optional[float] = None

class ImagesRequest(BaseModel):
    local_image_paths: List[str]
    file_prefix: Optional[str] = ""
    use_inpainting: Optional[bool] = False
    toggle_states: Optional[dict] = None
    unwanted_texts: Optional[dict] = None
    watermark_text: Optional[str] = None
    watermark_opacity: Optional[float] = None

# FastAPI 앱 생성
def create_app(image_processor: ImageProcessor, max_workers: int = 2):
    app = FastAPI()
    executor = ThreadPoolExecutor(max_workers=max_workers)

    @app.post("/translate_image")
    async def translate_image(req: ImageRequest):
        # 워터마크 관련 옵션을 toggle_states에 병합
        toggle_states = req.toggle_states.copy() if req.toggle_states else {}
        if req.watermark_text is not None:
            toggle_states["watermark_text"] = req.watermark_text
        if req.watermark_opacity is not None:
            toggle_states["watermark_opacity"] = req.watermark_opacity
        # 단일 이미지 번역
        result = await image_processor.process_single_image(
            toggle_states, req.unwanted_texts or {}, req.local_image_path, 0, req.file_prefix
        )
        # 경로만 반환
        if isinstance(result, dict):
            return {"result": result.get("path", None)}
        return {"result": result}

    @app.post("/translate_images")
    async def translate_images(req: ImagesRequest):
        # 워터마크 관련 옵션을 toggle_states에 병합
        toggle_states = req.toggle_states.copy() if req.toggle_states else {}
        if req.watermark_text is not None:
            toggle_states["watermark_text"] = req.watermark_text
        if req.watermark_opacity is not None:
            toggle_states["watermark_opacity"] = req.watermark_opacity
        # 여러 이미지 병렬 번역
        loop = asyncio.get_event_loop()
        tasks = []
        sem = asyncio.Semaphore(max_workers)
        async def sem_task(idx, path):
            async with sem:
                return await image_processor.process_single_image(
                    toggle_states, req.unwanted_texts or {}, path, idx, req.file_prefix
                )
        for idx, path in enumerate(req.local_image_paths):
            tasks.append(sem_task(idx, path))
        results = await asyncio.gather(*tasks)
        # 경로만 리스트로 반환
        def extract_path(res):
            if isinstance(res, dict):
                return res.get("path", None)
            return res
        return {"results": [extract_path(r) for r in results]}

    return app

# 서버 실행 함수
def run_server(image_processor, max_workers=2):
    port = find_free_port()
    app = create_app(image_processor, max_workers)
    uvicorn.run(app, host="127.0.0.1", port=port, workers=1)
    # FastAPI의 workers는 프로세스 수이므로, 내부 병렬은 ThreadPoolExecutor로 제어
    # 실제 워커 수는 process_single_image 병렬 호출로 제한
    # 서버 실행 후 포트 정보 반환 가능
    return port 