"""
"""


import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont
from .data import DataModeAutoDealPics


class OnePicDeal(object):
    def __init__(self,token):
        # 数据模型
        self.token = token
        self.data_mode_auto_deal_pics = DataModeAutoDealPics(token)

    def check_shoe_is_right(self, im=None, image_path=None):
        # 先进行API识别左右脚
        if im is None:
            im = Image.open(image_path)
        try:
            r_data = self.data_mode_auto_deal_pics.check_is_right_foot_by_api(image=im)
        except BaseException as e:
            r_data = None
            print("20", e)

        flag = self.check_shoe_is_right_by_pixel(im=im)
        if r_data:
            if "拖鞋" in r_data:
                flag = flag is not True
        if flag:
            print("自动识别----->这是左脚")
        else:
            print("自动识别----->这是右脚")
        return flag

    def check_shoe_is_right_by_pixel(self, im=None, image_path=None):
        if im is None:
            im = Image.open(image_path)
        # 注意，只支持透明图
        # 打开图像文件
        im = im.crop(im.getbbox())
        # image.show()
        # 获取图像第一行的像素数据
        pixel_data = im.load()
        pix_list = []
        h = int(im.height / 20)
        for i in range(im.width):
            _r, _g, _b, _a = pixel_data[i, h]
            if _a > 10:
                pix_list.append(i)

        left_f_num = 0
        middle_w = int(im.width / 2)
        for i in pix_list:
            if i < middle_w:
                left_f_num += 1
            else:
                left_f_num -= 1
        if left_f_num > 0:
            return True
        else:
            return False

    def how_to_use(self):
        # 单图缩放处理
        a = {"command": "resize",
             "plugins_mode": "relative",  # pixel 相对（宽度、高度、其他参考图），或绝对像素
             "base_im": {"im": "im"},  # 参考基于其他图 PIL格式
             "base": "width",  # base:pixel,width,height,by_im 基于长边、基于短边  （基于短边时，则缩放到指定尺寸）by_im确保能塞进参考图内
             "value": 649,  # 固定值，如果为百分比，则为0
             "percentage": 0, }  # 百分比

        # 单图圆角处理
        a = {"command": "radius",  # radius
             "plugins_mode": "relative",  # pixel 相对（短边），或绝对像素
             "circular_pos": (0, 1, 0, 1),  # 从左上角顺时针，记录圆角数量
             "value": 649,  # 固定值，如果为百分比，则为0
             "percentage": 0, }  # 百分比

        # 单图处理成圆形
        a = {"command": "circular",  # circular
             }

        # 单图旋转处理
        a = {"command": "rotate",
             "plugins_mode": "",
             "value": 649,  # 固定值 顺时针
             }

        # 图片粘贴处理
        a = {
            "command": "paste_img",
            "img": {"im": "im"},
            "pos": {"plugins_mode": "relative",  # pixel
                    "base": "center",  # nw,nc,ne,ec ... 各个方向参考点
                    "value": (100, 100),
                    "percentage": (0.5, 0.5),
                    },
            "margins": (0, 0, 0, 0),  # 上下左右边距
        }

        # 图片剪裁处理
        a = {
            "command": "crop_img",
            "img": {"im": "im"},
            "pos": {"plugins_mode": "relative",  # pixel
                    "base": "center",  # nw,nc,ne,ec ... 各个方向参考点
                    "value": (100, 100, 10, 10),
                    },
            "color_fill": (255, 255, 255)
        }

        # 图片添加文字
        a = {
            "command": "add_text",
            "pos": {"plugins_mode": "relative",  # pixel
                    "base": "center",  # nw,nc,ne,ec ... 各个方向参考点
                    "value": (100, 100),
                    "percentage": 0, },
            "font": "",
            "text": "",
            "anchor": "",  # mm 为居中 ma 为左右居中，上面居顶
            "align": "对齐方式",
            "direction": "文本的方向",
            "max_len_one_line": "单行长度",
            "spacing": 10,
            "fill": "文字颜色",
        }

    def add_text(self, img: Image, command):
        draw_1 = ImageDraw.Draw(img)
        # 定义字体，你需要有一个.ttf字体文件
        font = command["font"]
        text = command["text"]
        spacing = 4 if not command["spacing"] else command["spacing"]
        fill = command["fill"]
        anchor = None if not command["anchor"] else command["anchor"]
        align = "left" if not command["align"] else command["align"]  # left, center 或 right
        _, _, text_width, text_height = draw_1.textbbox((0, 0), text, font=font)

        xy = (0, 0)
        if command["pos"]["plugins_mode"] == "pixel":
            value = command["pos"]["value"]
            xy = value

        draw_1.multiline_text(xy, text,
                              fill=fill,
                              font=font,
                              anchor=anchor,
                              spacing=spacing,
                              align=align,
                              direction=None,
                              features=None,
                              language=None,
                              stroke_width=0,
                              stroke_fill=None,
                              embedded_color=False)
        return img

    def resize(self, img: Image, command):
        if command["plugins_mode"] == "pixel":
            if command["base"] == "width":
                img = self.to_resize(img, width=command["value"])
            if command["base"] == "high":
                img = self.to_resize(img, height=command["value"])
        # 相对值
        if command["plugins_mode"] == "relative":
            base_im = command["base_im"]["im"]
            if command["base"] == "width":
                img = self.to_resize(img, width=img.width * command["percentage"] if not base_im else int(
                    base_im.width * command["percentage"]))
            if command["base"] == "height":
                img = self.to_resize(img, width=img.height * command["percentage"] if not base_im else int(
                    base_im.height * command["percentage"]))
            # by_im确保能塞进参考图内
            if command["base"] == "by_im":
                percentage = 1 if not command["percentage"] else command["percentage"]
                box_width, box_height = int(base_im.width * percentage), int(base_im.height * percentage)
                width, height = img.width, img.height
                if box_width / box_height < width / height:
                    scale = box_width / width
                else:
                    scale = box_height / height
                img = img.resize((int(width * scale), int(height * scale)))
        # img.show()
        return img

    def paste_img(self, img: Image, command):
        # 粘贴绝对像素
        base = "nw" if not command["pos"]["base"] else command["pos"]["base"]
        value = command["pos"]["value"]
        percentage = (0, 0) if not command["pos"]["percentage"] else command["pos"]["percentage"]

        if command["margins"]:
            top, down, left, right = command["margins"]
        else:
            top, down, left, right = 0, 0, 0, 0

        if percentage != (0, 0):  # percentage 不按占比模式
            if base in ("nw", "wn", "wc", "cw", "nc", "cn", "center"):
                value = (int(img.width), int(img.height))
            if base in ("sw", "ws", "sc", "cs", "center"):
                value = (int(img.width), -1 * int(img.height))
            if base in ("ec", "ce"):
                value = (int(img.width), int(img.height))

        img_1 = command["img"]["im"]
        if command["pos"]["plugins_mode"] == "pixel":
            if base == "ec" or "ce":
                p_x = int(img.width - img_1.width) + value[0]
                p_y = value[1]
            if base == "nw" or "wn":
                deviation_x, deviation_y = 0, 0
                p_x, p_y = value

            if base == "cs" or "sc":
                p_x, p_y = value
            if base == "center":
                deviation_x, deviation_y = int((img.width - img_1.width) / 2), int((img.height - img_1.height) / 2)
                p_x = deviation_x + value[0] + left
                p_y = deviation_y + value[1] + top
            if base == "sw" or base == "ws":
                # deviation_x, deviation_y = 0, int((img.height - img_1.height))
                p_x = value[0] + left
                p_y = img.height - (img_1.height + value[1] + down)
            if base == "wc" or base == "cw":
                p_x = value[0] + left
                p_y = int((img.height - img_1.height) / 2) + value[1] + top

            try:
                img.paste(img_1, (p_x, p_y), img_1)
            except:
                img.paste(img_1, (p_x, p_y), img_1.convert("RGBA"))

        return img

    def crop_img(self, img: Image, command):
        base = "nw" if not command["pos"]["base"] else command["pos"]["base"]
        # print(base)
        value = command["pos"]["value"]
        percentage = command["pos"]["percentage"]

        if command["margins"]:
            top, down, left, right = command["margins"]
        else:
            top, down, left, right = 0, 0, 0, 0

        out_img_size = (value[2], value[3])
        # 默认填充色
        color_fill = command["color_fill"]
        if not color_fill:
            color_fill = (0, 0, 0)

        if command["pos"]["plugins_mode"] == "pixel":
            if base == "nw" or "wn":
                box = value
            if base == "sw" or base == "ws":
                # deviation_x, deviation_y = 0, int((img.height - img_1.height))
                box = (value[0], img.height - (value[1] + value[3]), value[2], value[3])
                print(box)

            if base == "se" or base == "es":
                box = (img.width - (value[0] + value[2]), img.height - (value[1] + value[3]), value[2], value[3])
                print(box)
            box = [box[0], box[1], box[0] + box[2], box[1] + box[3]]

        print("box", box)
        print("img.width", img.width)
        print("img.height", img.height)

        out_img = img.crop(box=box)
        print(out_img.size)
        # out_img.show()
        if box[0] < 0:
            out_img.paste(Image.new("RGB", (-1 * box[0], out_img.height), color_fill), (0, 0))
        # print(img.width, box)

        if box[2] > img.width:
            # print(box[2] - img.width, img.height)
            i = Image.new("RGB", (box[2] - img.width, out_img.height), color_fill)
            out_img.paste(i, (img.width - box[0], 0))
        if box[1] < 0:
            out_img.paste(Image.new("RGB", (img.width, -1 * box[1]), color_fill), (0, 0))

        if box[3] > img.height:
            out_img.paste(Image.new("RGB", (out_img.width, box[3] - img.height), color_fill),
                          (0, img.height - box[1]))

        # bg_img = Image.new("RGB", out_img_size, color_fill)
        # if box[0] < 0:
        #     x = -1 * box[0]
        # elif box[2] > img.width:
        #     x = img.width - box[2]
        # else:
        #     x = 0
        #
        # if box[1] < 0:
        #     y = -1 * box[1]
        # elif box[2] > img.height:
        #     y = img.height - box[1]
        # else:
        #     y = 0
        # bg_img.paste(img, box=(x, y), )

        # print(box)
        # img = img.crop(box=box)
        # out_img.show()
        return out_img

    def radius(self, img: Image, command):
        # 单图圆角处理

        radii = command["value"]
        if radii > img.width / 2:
            radii = int(img.width / 2)
        if radii > img.height / 2:
            radii = int(img.height / 2)

        # 画圆（用于分离4个角）
        circle = Image.new('L', (radii * 2, radii * 2), 0)  # 创建一个黑色背景的画布
        draw = ImageDraw.Draw(circle)
        draw.ellipse((0, 0, radii * 2, radii * 2), fill=255)  # 画白色圆形

        # 原图
        img = img.convert("RGBA")
        w, h = img.size

        # 画4个角（将整圆分离为4个部分）
        alpha = Image.new('L', img.size, 255)
        _pos = command["circular_pos"]
        if not _pos:
            _pos = (1, 1, 1, 1)
        for index, i in enumerate(_pos):
            if index == 0 and i == 1:
                alpha.paste(circle.crop((0, 0, radii, radii)), (0, 0))  # 左上角
            if index == 1 and i == 1:
                alpha.paste(circle.crop((radii, 0, radii * 2, radii)), (w - radii, 0))  # 右上角
            if index == 2 and i == 1:
                alpha.paste(circle.crop((radii, radii, radii * 2, radii * 2)), (w - radii, h - radii))  # 右下角
            if index == 3 and i == 1:
                alpha.paste(circle.crop((0, radii, radii, radii * 2)), (0, h - radii))  # 左下角
        # alpha.show()
        img.putalpha(alpha)  # 白色区域透明可见，黑色区域不可见
        return img

    def to_resize(self, _im, width=None, height=None):
        _im_x, _im_y = _im.size
        if width and height:
            if _im_x >= _im_y:
                height = None
            else:
                width = None
        if width:
            re_x = int(width)
            re_y = int(_im_y * re_x / _im_x)
        else:
            re_y = int(height)
            re_x = int(_im_x * re_y / _im_y)
        _im = _im.resize((re_x, re_y))
        return _im

    def add_pic(self, detailed_images):
        if not detailed_images:
            return
        page_len = 0
        for index, im in enumerate(detailed_images):
            page_len += im.height
        bg_im = Image.new("RGB", (im.width, page_len), (255, 255, 255))

        n = 0
        for index, im in enumerate(detailed_images):
            bg_im.paste(im, (0, n))
            n += im.height
        # bg_im.show()
        return bg_im

    def get_goods_pos(self, im, cut_image):
        # 保留多余内容
        old_x, old_y = im.size
        x1, y1, x2, y2 = cut_image.getbbox()
        goods_w, goods_h = x2 - x1, y2 - y1
        _w, _h = int(goods_w / 10), int(goods_h / 10)  # 上下左右扩展位置
        new_x1, new_y1, new_x2, new_y2 = x1 - _w, y1 - _h, x2 + _w, y2 + _h  # 防止超限
        new_x1 = 0 if new_x1 < 0 else new_x1
        new_y1 = 0 if new_y1 < 0 else new_y1
        new_x2 = old_x if new_x2 > old_x else new_x2
        new_y2 = old_y if new_y2 > old_y else new_y2
        # 剪切掉多余的内容,保留阴影
        im = im.crop((new_x1, new_y1, new_x2, new_y2))  # 切图
        return im

    def deal_one_pic(self, data=None, is_show=False):
        """
        通用图片处理器
        1、图片位置处理
        输出拼接后的图片，以及拼接后商品所属位置
        """
        for command in data:
            if command["command"] == "paste_img":
                img1 = command["img1"]["im"]
                img2 = command["img2"]["im"]
                if "resize" in command["img2"]:
                    if "width" in command["img2"]["resize"]:
                        img2 = self.to_resize(img2, width=command["img2"]["resize"]["width"])
                        if is_show:
                            img2.show()
                img1.paste(img2, command["img2"]["pos"])
            if command["command"] == "image_crop":
                img1 = img1.crop(command["image_crop"])
        img = img1
        return img

    def deal_one_pic_2(self, orign_im, data=None):
        """
        通用图片处理器
        1、基于某原始图，进行加工，包括粘贴、单图处理等逻辑
        """
        # 单图缩放处理
        a = {"command": "resize",
             "plugins_mode": "relative",  # pixel 相对（宽度、高度、其他参考图），或绝对像素
             "base_im": "im",  # 参考基于其他图 PIL格式
             "base": "width",  # base:pixel,width,height,by_long_side,by_short_side基于长边、基于短边  （基于短边时，则缩放到指定尺寸）
             "value": 649,  # 固定值，如果为百分比，则为0
             "percentage": 0, }  # 百分比

        # 单图圆角处理
        a = {"command": "radius",  # radius
             "plugins_mode": "relative",  # pixel 相对（短边），或绝对像素
             "circular_pos": (0, 1, 0, 1),  # 从左上角顺时针，记录圆角数量
             "value": 649,  # 固定值，如果为百分比，则为0
             "percentage": 0, }  # 百分比

        # 单图处理成圆形
        a = {"command": "circular",  # circular
             }

        # 单图旋转处理
        a = {"command": "rotate",
             "plugins_mode": "",
             "value": 649,  # 固定值 顺时针
             }

        # 图片粘贴处理
        a = {
            "command": "paste_img",
            "img": {"im": "im"},
            "pos": {"plugins_mode": "relative",  # pixel
                    "base": "center",  # nw,nc,ne,ec ... 各个方向参考点
                    "value": (100, 100),
                    "percentage": 0, },
            "margins": (0, 0, 0, 0),  # 上下左右边距
        }

        # 图片剪裁处理
        a = {
            "command": "crop_img",
            "img": {"im": "im"},
            "plugins_mode": "relative",  # pixel
            "base": "center",  # nw,nc,ne,ec ... 各个方向参考点
            "box": (0, 0, 0, 0),
        }

        # 图片添加文字
        a = {
            "command": "add_text",
            "pos": {"plugins_mode": "relative",  # pixel
                    "base": "center",  # nw,nc,ne,ec ... 各个方向参考点
                    "value": (100, 100),
                    "percentage": 0, },
            "font": "",
            "text": "",
            "align": "对齐方式",
            "direction": "文本的方向",
            "fill": "文字颜色",
        }

        # 图片渐变处理
        # https://blog.csdn.net/skying159/article/details/119532479

        def get_value(data_dict, key):
            return 1

        r_dict = {"nw": 0,
                  }

        _r = 0
        for command in data:
            if command["command"] == "paste_img":
                img1 = command["img1"]["im"]
                img2 = command["img2"]["im"]
                if "resize" in command["img2"]:
                    if "width" in command["img2"]["resize"]:
                        img2 = self.to_resize(img2, width=command["img2"]["resize"]["width"])
                if "pos" in command["img2"]:
                    base = command["img2"]["base"]
                    value = command["img2"]["value"]
                    if command["img2"]["plugins_mode"] == "relative":
                        # 相对位置处理，居中比较特殊
                        # 其他的先进行旋转与镜像，处理后，进行反向操作
                        x, y = 0, 0
                        if base == "center":
                            x, y = int((img1.width - img2.width) / 2), int((img1.height - img2.height) / 2)

                        if base == "nw" or base == "nw":
                            pass

                        w, h = img1.width * value[0], img1.height * value[0]

                img1.paste(img2, command["img2"]["pos"])
                if _r != 0:
                    img1 = img1.rotate(_r * -1)
                continue
            if command["command"] == "image_crop":
                img1 = img1.crop(command["image_crop"])
                continue
        img = img1
        return img

    def get_overlay_pic(self, pil_img_1, pil_img_2, color):
        im_w, im_h = pil_img_1.size
        cv_im = cv2.cvtColor(np.asarray(pil_img_1), cv2.COLOR_RGB2BGR)

        # 创建一张纯色底图
        image_white = Image.new("RGB", (im_w, im_h), color)

        cv_image_white = cv2.cvtColor(np.asarray(image_white), cv2.COLOR_RGB2BGR)
        new_im = self.to_color_2(cv_image_white, cv_im)
        # new_im = cv2.addWeighted(new_im, 0.7, cv_im_2, 0.3, 0)
        # new_im = cv2.add(new_im, cv_im_2)

        new_im = Image.fromarray(cv2.cvtColor(new_im, cv2.COLOR_BGR2RGB))
        new_im.paste(pil_img_2, (0, 0), pil_img_2)
        return new_im

    def to_color_2(self, target, blend):  # 正片叠底
        return np.array(np.multiply(target / 256, blend / 256) * 256, dtype=np.uint8)

    def to_color_1(self, img1, img2):  # PS颜色模式
        img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
        img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV)
        img2[:, :, 0] = img1[:, :, 0]
        img2[:, :, 1] = img1[:, :, 1]
        res = cv2.cvtColor(img2, cv2.COLOR_HSV2BGR)
        return res


if __name__ == '__main__':
    from collections import defaultdict


    def set_dict(one_dict):
        _ = defaultdict(str)
        for i, v in one_dict.items():
            if isinstance(v, dict):
                v = set_dict(v)
            _[i] = v
        return _


    def deal_one_pic(img: Image, data=None):
        """
        通用图片处理器
        1、基于某原始图，进行加工，包括粘贴、单图处理等逻辑
        """
        data = [set_dict(x) for x in data]

        for command in data:
            if command["command"] == "resize":
                img = OnePicDeal().resize(img, command)
                continue
            if command["command"] == "paste_img":
                img = OnePicDeal().paste_img(img, command)
                continue
            if command["command"] == "crop_img":
                img = OnePicDeal().crop_img(img, command)
                continue
            if command["command"] == "radius":
                img = OnePicDeal().radius(img, command)
                continue
            if command["command"] == "add_text":
                img = OnePicDeal().add_text(img, command)
                continue

        return img


    image_path = r"D:\MyDocuments\PythonCode\MyPython\red_dragonfly\deal_pics\auto_capture_V2\IPC\output\-秋季订货会夏季补充给葛明明\NUM24106316\阴影图处理\NUM24106316（3）_后跟_阴影.png"
    to_paste_img = Image.open(image_path)
    data = []
    bg_color = (246, 246, 246)
    # 单图缩放处理
    view = "后跟"
    data.append({"command": "resize",
                 "plugins_mode": "pixel",  # pixel 相对（宽度、高度、其他参考图），或绝对像素
                 "base_im": {"im": ""},  # 参考基于其他图 PIL格式
                 "base": "width",  # base:pixel,width,height,by_im 基于长边、基于短边  （基于短边时，则缩放到指定尺寸）by_im确保能塞进参考图内
                 "value": 1300 if view == "后跟" else 2200,  # 固定值，如果为百分比，则为0
                 "percentage": 0, })  # 百分比

    view_dict = {"俯视": (0, 0, 1100, 1200),
                 "内里": (-1, -100, 1100, 1200),
                 "后跟": (0, -100, 1100, 1200),
                 "鞋底": (0, -100, 1100, 1200),
                 }

    data.append({
        "command": "crop_img",
        "img": "",
        "pos": {"plugins_mode": "pixel",  # pixel
                "base": "sw",  # nw,nc,ne,ec ... 各个方向参考点
                "value": view_dict[view],
                },
        "color_fill": bg_color,
    })

    # 处理圆角
    data.append({"command": "radius",  # radius
                 "plugins_mode": "relative",  # pixel 相对（短边），或绝对像素
                 "circular_pos": (1, 0, 0, 1),  # 从左上角顺时针，记录圆角数量
                 "value": 100,  # 固定值，如果为百分比，则为0
                 "percentage": 0, })  # 百分比

    to_paste_img = deal_one_pic(to_paste_img, data)
    # print(to_paste_img.size)

    # 粘贴到白底图上
    img = Image.new("RGB", (1200, 1316), (255, 255, 255))
    data = []
    data.append({
        "command": "paste_img",
        "img": {"im": to_paste_img},
        "pos": {"plugins_mode": "pixel",  # pixel  relative
                "base": "wc",  # nw,nc,ne,ec,... 各个方向参考点
                "value": (100, 0),
                "percentage": "",
                },
        "margins": (0, 0, 0, 0),  # 上下左右边距
    })
    img = deal_one_pic(img, data)
    img.show()
