import logging

import cv2
import numpy as np

from app.service.utils.new_oss_client import oss_get_image

logger = logging.getLogger()


class Color:
    def __init__(self, minio_client):
        self.minio_client = minio_client

    def __call__(self, result):
        dim_image_h, dim_image_w = result['image'].shape[0:2]
        # 渐变色
        if "gradient" in result.keys() and result['gradient'] != "":
            bucket_name = result['gradient'].split('/')[0]
            object_name = result['gradient'][result['gradient'].find('/') + 1:]
            pattern = self.get_gradient(bucket_name=bucket_name, object_name=object_name)
            resize_pattern = cv2.resize(pattern, (dim_image_w, dim_image_h), interpolation=cv2.INTER_AREA)
        # 无色
        elif "color" not in result.keys() or result['color'] == "":
            result['final_image'] = result['pattern_image'] = result['single_image'] = result['image']
            result['alpha'] = 100 / 255.0
            return result
        # 正常颜色
        else:
            pattern = self.get_pattern(result['color'])
            resize_pattern = cv2.resize(pattern, (dim_image_w, dim_image_h), interpolation=cv2.INTER_AREA)

        if "partial_color" in result.keys() and result['partial_color'] != "":
            bucket_name = result['partial_color'].split('/')[0]
            object_name = result['partial_color'][result['partial_color'].find('/') + 1:]
            partial_color = oss_get_image(oss_client=self.minio_client, bucket=bucket_name, object_name=object_name, data_type="cv2")
            h, w = partial_color.shape[0:2]
            resize_pattern = cv2.resize(resize_pattern, (w, h), interpolation=cv2.INTER_AREA)
            # 分离出 png 图的 alpha 通道
            alpha_channel = partial_color[:, :, 3]
            # 提取 png 图的 RGB 通道
            png_rgb = partial_color[:, :, :3]
            # 创建一个与 cv 图大小相同的掩码，用于指示哪些像素需要替换
            mask = alpha_channel > 0
            # 将掩码扩展为 3 通道，以便与 cv 图进行逐元素操作
            mask_3ch = np.stack([mask] * 3, axis=-1)
            # 根据掩码将 png 图的颜色覆盖到 cv 图上
            resize_pattern[mask_3ch] = png_rgb[mask_3ch]
            resize_pattern = cv2.resize(resize_pattern, (dim_image_w, dim_image_h), interpolation=cv2.INTER_AREA)
        closed_mo = np.expand_dims(result['mask'], axis=2).repeat(3, axis=2)
        gray_mo = np.expand_dims(result['gray'], axis=2).repeat(3, axis=2)
        get_image_fir = resize_pattern * (closed_mo / 255) * (gray_mo / 255)
        result['pattern_image'] = get_image_fir.astype(np.uint8)
        result['final_image'] = result['pattern_image']
        canvas = np.full_like(result['final_image'], 255)
        temp_bg = np.expand_dims(cv2.bitwise_not(result['mask']), axis=2).repeat(3, axis=2)
        tmp1 = (canvas * (temp_bg / 255)).astype(np.uint8)
        temp_fg = np.expand_dims(result['mask'], axis=2).repeat(3, axis=2)
        tmp2 = (result['final_image'] * (temp_fg / 255)).astype(np.uint8)
        result['single_image'] = cv2.add(tmp1, tmp2)
        result['alpha'] = 100 / 255.0
        return result

    def get_gradient(self, bucket_name, object_name):
        # 获取渐变色图案
        image = oss_get_image(oss_client=self.minio_client, bucket=bucket_name, object_name=object_name, data_type="cv2")
        if image.shape[2] == 4:
            image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)
        return image

    @staticmethod
    def crop_image(image, image_size_h, image_size_w):
        x_offset = np.random.randint(low=0, high=int(image_size_h / 5) - 6)
        y_offset = np.random.randint(low=0, high=int(image_size_w / 5) - 6)
        image = image[x_offset: x_offset + image_size_h, y_offset: y_offset + image_size_w, :]
        return image

    @staticmethod
    def get_pattern(single_color):
        if single_color is None:
            raise False
        R, G, B = single_color.split(' ')
        pattern = np.zeros([1, 1, 3], np.uint8)
        pattern[0, 0, 0] = int(B)
        pattern[0, 0, 1] = int(G)
        pattern[0, 0, 2] = int(R)
        return pattern
