import json
import logging

from fastapi import APIRouter, BackgroundTasks, HTTPException

from app.schemas.generate_image import GenerateImageModel, GenerateProductImageModel, GenerateSingleLogoImageModel, GenerateRelightImageModel, GenerateMultiViewModel, BatchGenerateProductImageModel, BatchGenerateRelightImageModel, AgentTollGenerateImageModel
from app.schemas.pose_transform import BatchPoseTransformModel
from app.schemas.response_template import ResponseModel
from app.service.generate_batch_image.service import start_product_batch_generate, start_relight_batch_generate, start_pose_transform_batch_generate
from app.service.generate_image.service_agent_tool_generate_image import AgentToolGenerateImage
from app.service.generate_image.service_generate_image import GenerateImage, infer_cancel as generate_image_infer_cancel
from app.service.generate_image.service_generate_multi_view import GenerateMultiView, infer_cancel as generate_multi_view_cancel
from app.service.generate_image.service_generate_product_image import GenerateProductImage, infer_cancel as generate_product_image_cancel
from app.service.generate_image.service_generate_relight_image import GenerateRelightImage, infer_cancel as generate_relight_image_cancel
from app.service.generate_image.service_generate_single_logo import GenerateSingleLogoImage, infer_cancel as generate_single_logo_cancel

router = APIRouter()
logger = logging.getLogger()

'''generate image'''


@router.post("/generate_image")
def generate_image(request_item: GenerateImageModel, background_tasks: BackgroundTasks):
    """
        创建一个具有以下参数的请求体:
        - **tasks_id**: 任务id 用于取消生成任务和获取生成结果
        - **prompt**: 想要生成图片的描述词
        - **image_url**: 图生图的输入，minio或S3 url 地址
        - **mode**: 生成模式，img2img或者txt2img
        - **category**: 生成图片的类别，sketch print 等等
        - **gender**: 生成sketch专用，服装类别
        - **version**: 使用模型版本 fast 或者 high

        示例参数：
        {
          "tasks_id": "123-89",
          "prompt": "skeleton sitting by the side of a river looking soulful, concert poster, 4k, artistic",
          "image_url": "aida-collection-element/87/Printboard/842c09cf-7297-42d9-9e6e-9c17d4a13cb5.jpg",
          "mode": "img2img",
          "category": "sketch",
          "gender": "male",
          "version": "fast"
        }
    """
    try:
        logger.info(f"generate_image request item is : @@@@@@:{json.dumps(request_item.dict())}")
        service = GenerateImage(request_item)
        background_tasks.add_task(service.get_result)
    except Exception as e:
        logger.warning(f"generate_image Run Exception @@@@@@:{e}")
        raise HTTPException(status_code=404, detail=str(e))
    return ResponseModel()


@router.get("/generate_cancel/{tasks_id}")
def generate_image(tasks_id: str):
    try:
        logger.info(f"generate_cancel request item is : @@@@@@:{tasks_id}")
        data = generate_image_infer_cancel(tasks_id)
        logger.info(f"generate_cancel response @@@@@@:{data}")
    except Exception as e:
        logger.warning(f"generate_cancel Run Exception @@@@@@:{e}")
        raise HTTPException(status_code=404, detail=str(e))
    return ResponseModel(data=data['data'])


'''multi view'''


@router.post("/generate_multi_view")
def generate_multi_view(request_item: GenerateMultiViewModel, background_tasks: BackgroundTasks):
    """
        创建一个具有以下参数的请求体:
        - **tasks_id**: 任务id 用于取消生成任务和获取生成结果
        - **image_url**: 前视角图的输入，minio或S3 url 地址

        示例参数：
        {
          "tasks_id": "123-89",
          "image_url": "aida-collection-element/87/Printboard/842c09cf-7297-42d9-9e6e-9c17d4a13cb5.jpg"
        }
    """
    try:
        logger.info(f"generate_multi_view request item is : @@@@@@:{json.dumps(request_item.dict())}")
        service = GenerateMultiView(request_item)
        background_tasks.add_task(service.get_result)
    except Exception as e:
        logger.warning(f"generate_multi_view Run Exception @@@@@@:{e}")
        raise HTTPException(status_code=404, detail=str(e))
    return ResponseModel()


@router.get("/generate_multi_view_cancel/{tasks_id}")
def generate_multi_view(tasks_id: str):
    try:
        logger.info(f"generate_cancel request item is : @@@@@@:{tasks_id}")
        data = generate_multi_view_cancel(tasks_id)
        logger.info(f"generate_cancel response @@@@@@:{data}")
    except Exception as e:
        logger.warning(f"generate_cancel Run Exception @@@@@@:{e}")
        raise HTTPException(status_code=404, detail=str(e))
    return ResponseModel(data=data['data'])


'''single logo'''


@router.post("/generate_single_logo")
def generate_single_logo(request_item: GenerateSingleLogoImageModel, background_tasks: BackgroundTasks):
    """
        创建一个具有以下参数的请求体:
        - **tasks_id**: 任务id 用于取消生成任务和获取生成结果
        - **prompt**: 想要生成图片的描述词
        - **seed**: 固定的prompt和固定的seed 每次的生成结果都是一样的

        示例参数：
        {
          "tasks_id": "123-89",
          "prompt": "an apple",
          "seed": "2"
        }
    """
    try:
        logger.info(f"generate_single_logo request item is : @@@@@@:{json.dumps(request_item.dict())}")
        service = GenerateSingleLogoImage(request_item)
        background_tasks.add_task(service.get_result)
    except Exception as e:
        logger.warning(f"generate_single_logo Run Exception @@@@@@:{e}")
        raise HTTPException(status_code=404, detail=str(e))
    return ResponseModel()


@router.get("/generate_single_logo_cancel/{tasks_id}")
def generate_single_logo_image(tasks_id: str):
    try:
        logger.info(f"generate_single_logo_cancel request item is : @@@@@@:{tasks_id}")
        data = generate_single_logo_cancel(tasks_id)
        logger.info(f"generate_single_logo_cancel response @@@@@@:{data}")
    except Exception as e:
        logger.warning(f"generate_single_logo_cancel Run Exception @@@@@@:{e}")
        raise HTTPException(status_code=404, detail=str(e))
    return ResponseModel(data=data['data'])


'''product image'''


@router.post("/generate_product_image")
def generate_product_image(request_item: GenerateProductImageModel, background_tasks: BackgroundTasks):
    """
        创建一个具有以下参数的请求体:
        - **tasks_id**: 任务id 用于取消生成任务和获取生成结果
        - **prompt**: 想要生成图片的描述词
        - **image_url**: 被生成图片的S3或minio url地址
        - **image_strength**: 生成强度，越低越接近原图
        - **product_type**: 输入single item 还是 overall item


        示例参数：
        {
          "tasks_id": "123-89",
          "prompt": "the best quality, masterpiece. detailed, high-res, simple background, studio photography, extremely detailed, updo, detailed face, face, close-up, HDR, UHD, 8K realistic, Highly detailed, simple background, Studio lighting",
          "image_url": "aida-results/result_00097282-ebb2-11ee-a822-b48351119060.png",
          "image_strength": 0.8,
          "product_type": "overall"
        }
    """
    try:
        logger.info(f"generate_product_image request item is : @@@@@@:{json.dumps(request_item.dict())}")
        service = GenerateProductImage(request_item)
        background_tasks.add_task(service.get_result)
    except Exception as e:
        logger.warning(f"generate_product_image Run Exception @@@@@@:{e}")
        raise HTTPException(status_code=404, detail=str(e))
    return ResponseModel()


@router.get("/generate_product_image_cancel_cancel/{tasks_id}")
def generate_product_image(tasks_id: str):
    try:
        logger.info(f"generate_product_image_cancel_cancel request item is : @@@@@@:{tasks_id}")
        data = generate_product_image_cancel(tasks_id)
        logger.info(f"generate_product_image_cancel_cancel response @@@@@@:{data}")
    except Exception as e:
        logger.warning(f"generate_product_image_cancel_cancel Run Exception @@@@@@:{e}")
        raise HTTPException(status_code=404, detail=str(e))
    return ResponseModel(data=data['data'])


'''relight image'''


@router.post("/generate_relight_image")
def generate_relight_image(request_item: GenerateRelightImageModel, background_tasks: BackgroundTasks):
    """
        创建一个具有以下参数的请求体:
        - **tasks_id**: 任务id 用于取消生成任务和获取生成结果
        - **prompt**: 想要生成图片的描述词
        - **image_url**: 被生成图片的S3或minio url地址
        - **direction**: 光源方向  Right Light      Left Light      Top Light     Bottom Light
        - **product_type**: 输入single item 还是 overall item


        示例参数：
        {
          "tasks_id": "123-89",
          "prompt": "beautiful woman, detailed face, sunshine, outdoor, warm atmosphere",
          "image_url": "aida-results/result_0000b606-1902-11ef-9424-0242ac180002.png",
          "direction": "Right Light",
          "product_type": "overall"
        }
    """
    try:
        logger.info(f"generate_relight_image request item is : @@@@@@:{json.dumps(request_item.dict())}")
        service = GenerateRelightImage(request_item)
        background_tasks.add_task(service.get_result)
    except Exception as e:
        logger.warning(f"generate_relight_image Run Exception @@@@@@:{e}")
        raise HTTPException(status_code=404, detail=str(e))
    return ResponseModel()


@router.get("/generate_relight_image_cancel_cancel/{tasks_id}")
def generate_relight_image(tasks_id: str):
    try:
        logger.info(f"generate_relight_image_cancel_cancel request item is : @@@@@@:{tasks_id}")
        data = generate_relight_image_cancel(tasks_id)
        logger.info(f"generate_relight_image_cancel_cancel response @@@@@@:{data}")
    except Exception as e:
        logger.warning(f"generate_relight_image_cancel_cancel Run Exception @@@@@@:{e}")
        raise HTTPException(status_code=404, detail=str(e))
    return ResponseModel(data=data['data'])


"""batch generate img"""


@router.post("/batch_generate_product_image")
async def batch_generate_product(request_batch_item: BatchGenerateProductImageModel):
    """
        创建一个具有以下参数的请求体:
        - **tasks_id**: 任务id 用于获取生成结果
        - **prompt**: 想要生成图片的描述词
        - **image_url**: 被生成图片的S3或minio url地址
        - **image_strength**: 生成强度，越低越接近原图
        - **product_type**: 输入single item 还是 overall item
        - **batch_size**: 批生成数量


        示例参数：
        {
          "tasks_id": "123-89",
          "prompt": "the best quality, masterpiece. detailed, high-res, simple background, studio photography, extremely detailed, updo, detailed face, face, close-up, HDR, UHD, 8K realistic, Highly detailed, simple background, Studio lighting",
          "image_url": "aida-results/result_00097282-ebb2-11ee-a822-b48351119060.png",
          "image_strength": 0.8,
          "product_type": "overall",
          "batch_size": 1
        }
    """
    return await start_product_batch_generate(request_batch_item)


@router.post("/batch_generate_relight_image")
async def batch_generate_relight(request_batch_item: BatchGenerateRelightImageModel):
    """
        创建一个具有以下参数的请求体:
        - **tasks_id**: 任务id 用于获取生成结果
        - **prompt**: 想要生成图片的描述词
        - **image_url**: 被生成图片的S3或minio url地址
        - **direction**: 光源方向  Right Light      Left Light      Top Light     Bottom Light
        - **product_type**: 输入single item 还是 overall item
        - **batch_size**: 批生成数量


        示例参数：
        {
          "tasks_id": "123-89",
          "prompt": "beautiful woman, detailed face, sunshine, outdoor, warm atmosphere",
          "image_url": "aida-results/result_0000b606-1902-11ef-9424-0242ac180002.png",
          "direction": "Right Light",
          "product_type": "overall",
          "batch_size": 1
        }
    """
    return await start_relight_batch_generate(request_batch_item)


@router.post("/batch_generate_pose_transform_image")
async def batch_generate_pose_transform(request_batch_item: BatchPoseTransformModel):
    """
        创建一个具有以下参数的请求体:
        - **tasks_id**: 任务id 用于取消生成任务和获取生成结果
        - **image_url**: 被生成图片的S3或minio url地址
        - **pose_id**: 1
        - **batch_size**: 批生成数量


        示例参数：
        {
          "tasks_id": "123-89",
          "image_url": "aida-results/result_0000b606-1902-11ef-9424-0242ac180002.png",
          "pose_id": "1",
          "batch_size": 1
        }
    """
    return await start_pose_transform_batch_generate(request_batch_item)


"""agent tool"""


@router.post("/agent_tool_generate_image")
def agent_tool_generate_image(request_item: AgentTollGenerateImageModel, background_tasks: BackgroundTasks):
    """
        创建一个具有以下参数的请求体:
        - **prompt**: 想要生成图片的描述词
        - **category**: 生成图片的类别，sketch print 等等
        - **gender**: 生成sketch专用，服装类别
        - **version**: 使用模型版本 fast 或者 high
        - **size**: 生成数量
        - **version**: 使用模型版本 fast 或者 high


        示例参数：
        {
          "prompt": "a single item of sketch of Wabi-sabi, skirt, tiered, 4k, white background",
          "category": "sketch",
          "gender": "male",
          "size":2,
          "version":"high"
        }
    """
    try:
        logger.info(f"agent_tool_generate_image request item is : @@@@@@:{request_item.dict()}")
        request_data = request_item.dict()
        service = AgentToolGenerateImage(request_data['version'])
        image_url_list, clothing_category_list = service.get_result(
            prompt=request_data['prompt'],
            size=request_data['size'],
            version=request_data['version'],
            category=request_data['category'],
            gender=request_data['gender']
        )
        data = {
            "image_url_list": image_url_list,
            "clothing_category_list": clothing_category_list
        }
        logger.info(f"agent_tool_generate_image response item is : @@@@@@:{data}")
    except Exception as e:
        logger.warning(f"agent_tool_generate_image Run Exception @@@@@@:{e}")
        raise HTTPException(status_code=404, detail=str(e))
    return ResponseModel(data=data)
