import cv2

from app.core.config import PRIORITY_DICT
from .builder import ITEMS
from .pipelines import Compose


@ITEMS.register_module()
class Clothing(object):
    def __init__(self, pipeline, **kwargs):
        self.pipeline = Compose(pipeline)
        self.result = dict(name=type(self).__name__.lower(), **kwargs)

    def process(self):
        self.pipeline(self.result)

    def apply_scale(self, img):
        scale = self.result['scale']
        height, width = img.shape[0: 2]
        if len(img.shape) > 2:
            height, width = img.shape[0: 2]
        scaled_img = cv2.resize(img, (int(width * scale), int(height * scale)), interpolation=cv2.INTER_AREA)
        return scaled_img

    def organize(self, layer):
        start_point = self.calculate_start_point(self.result['keypoint'], self.result['scale'], self.result['clothes_keypoint'], self.result['body_point_test'], self.result["offset"], self.result["resize_scale"])

        front_layer = dict(priority=self.result.get("priority", None) if self.result.get("layer_order", False) else PRIORITY_DICT.get(f'{type(self).__name__.lower()}_front', None),
                           name=f'{type(self).__name__.lower()}_front',
                           image=self.result["front_image"],
                           # mask_image=self.result['front_mask_image'],
                           image_url=self.result['front_image_url'],
                           mask_url=self.result['mask_url'],
                           sacle=self.result['scale'],
                           clothes_keypoint=self.result['clothes_keypoint'],
                           position=start_point,
                           resize_scale=self.result["resize_scale"],
                           mask=cv2.resize(self.result['mask'], self.result["front_image"].size),
                           gradient_string=self.result['gradient_string'] if 'gradient_string' in self.result.keys() else "",
                           pattern_image_url=self.result['pattern_image_url'],
                           pattern_image=self.result['pattern_image']

                           )
        layer.insert(front_layer)

        back_layer = dict(priority=-self.result.get("priority", 0) if self.result.get("layer_order", False) else PRIORITY_DICT.get(f'{type(self).__name__.lower()}_back', None),
                          name=f'{type(self).__name__.lower()}_back',
                          image=self.result["back_image"],
                          # mask_image=self.result['back_mask_image'],
                          image_url=self.result['back_image_url'],
                          mask_url=self.result['mask_url'],
                          sacle=self.result['scale'],
                          clothes_keypoint=self.result['clothes_keypoint'],
                          position=start_point,
                          resize_scale=self.result["resize_scale"],
                          mask=cv2.resize(self.result['mask'], self.result["front_image"].size),
                          gradient_string=self.result['gradient_string'] if 'gradient_string' in self.result.keys() else "",
                          pattern_image_url=self.result['pattern_image_url'],
                          )
        layer.insert(back_layer)

    @staticmethod
    def calculate_start_point(keypoint_type, scale, clothes_point, body_point, offset, resize_scale):
        """
        Align left
        Args:
            keypoint_type: string, "waistband" | "shoulder" | "ear_point"
            scale: float
            clothes_point: dict{'left': [x1, y1, z1], 'right': [x2, y2, z2]}
            body_point: dict, containing keypoint data of body figure

        Returns:
            start_point: tuple (x', y')
            x' = y_body - y1 * scale + offset
            y' = x_body - x1 * scale + offset

        """

        side_indicator = f'{keypoint_type}_left'

        # if keypoint_type == "ear_point":
        #     start_point = (body_point[side_indicator][1] - int(int(clothes_point[side_indicator].split("_")[1]) * scale),
        #                    body_point[side_indicator][0] - int(int(clothes_point[side_indicator].split("_")[0]) * scale))
        # else:
        #     start_point = (
        #         int(body_point[side_indicator][1] + offset[1] - int(clothes_point[side_indicator].split("_")[0]) * scale),  # y
        #         int(body_point[side_indicator][0] + offset[0] - int(clothes_point[side_indicator].split("_")[1]) * scale)  # x
        #     )

        # milvus_DB_keypoint_cache:
        start_point = (
            int(body_point[side_indicator][1] + offset[1] - int(clothes_point[side_indicator][0]) * scale),  # y
            int(body_point[side_indicator][0] + offset[0] - int(clothes_point[side_indicator][1]) * scale)  # x
        )
        # start_point = (
        #     int(body_point[side_indicator][1] + offset[1] - int(clothes_point[side_indicator].split("_")[0]) * scale),  # y
        #     int(body_point[side_indicator][0] + offset[0] - int(clothes_point[side_indicator].split("_")[1]) * scale)  # x
        # )

        return start_point
