from ..generate_goods_no_detail_pic.data import DataModeUploadPic
import os
import threading
import time
import concurrent.futures
import re
from PIL import Image
from io import BytesIO
from middleware import UnicornException

# 详情图上传
class UploadPic():
    # signal_data = Signal(dict)
    # run_end_sign = Signal(dict)
    # show_progress_detail_sign = Signal(str)

    def __init__(self, windows, to_deal_dir, config_data,token):
        super().__init__()
        self.windows = windows
        self.data_mode_upload_pic = DataModeUploadPic(token)
        self.goods_no_data = {}
        # ------------------
        # 0未选择文件，1已选文件未开始，2进行中
        self.state = 0
        self.state_change(self.state)
        self.to_deal_dir = to_deal_dir
        self.config_data = config_data

    def check_path(self, _path):
        if not os.path.exists(_path):
            os.mkdir(_path)
        return True

    def run_by_thread(self):
        self.run_by_thread_real()
        self.config_data["sign_text"] = "结束"
        self.run_end_sign.emit(self.config_data)

    def run(self):
        self.run_by_thread_real()

    def run_by_thread_real(self, *args):
        self.show_info("====开始处理====")
        # 统计哪些需要处理
        total_num = 0
        flag = True
        # group_folders 分组文件夹
        for group_folders in os.listdir(self.to_deal_dir):
            path = "{}\{}".format(self.to_deal_dir, group_folders)
            if not os.path.isdir(path):
                continue
            for goods_no in os.listdir(path):
                # 检测是不是货号或款号文件夹
                goods_no_path = "{}\{}\{}".format(self.to_deal_dir, group_folders, goods_no)
                if not os.path.isdir(goods_no_path):
                    continue

                total_num += 1
                # 检查每个款号文件夹是不是合规
                # 款的一级目录文件
                files = os.listdir(goods_no_path)
                if "details" not in files:
                    continue
                not_goods_art_msg = ""
                for f in files:
                    f_path = "{}\{}\{}\{}".format(self.to_deal_dir, group_folders, goods_no, f)
                    if os.path.isdir(f_path):
                        # 处理货号文件夹
                        if "details" != f and "货号素材" not in f and "main" not in f and "拼接图" not in f:
                            # 是否货号文件夹判断
                            if not self.is_goods_art_dir(f, goods_no):
                                self.show_info("{}文件夹下  {} {} 疑似不是货号".format(group_folders, goods_no, f))
                                not_goods_art_msg += (
                                    "{}文件夹下  {} {} 疑似不是货号".format(
                                        group_folders, goods_no, f
                                    )
                                    + "\n"
                                )
                                flag = False
        if not flag:
            self.show_info("请解决以上问题后重试")
            raise UnicornException(f"请解决:\n{not_goods_art_msg}\n以上问题后重试")
            return

        if total_num == 0:
            self.show_info("没有任何款号文件夹 需要上传")
            raise UnicornException("没有任何款号文件夹 需要上传")
            return

        self.lock = threading.Lock()

        error_data = []
        n = 0
        for group_folders in os.listdir(self.to_deal_dir):
            path = "{}\{}".format(self.to_deal_dir, group_folders)
            if not os.path.isdir(path):
                continue

            for goods_no in os.listdir(path):
                goods_no_path = "{}\{}\{}".format(self.to_deal_dir, group_folders, goods_no)
                if not os.path.isdir(goods_no_path):
                    self.show_info("{} 不是文件夹".format(goods_no))
                    continue
                if goods_no in self.data_mode_upload_pic.is_deal_goods_no:
                    continue
                else:
                    self.data_mode_upload_pic.is_deal_goods_no.append(goods_no)

                # ================处理单个款号信息，图片上传处理============
                self.show_info("开始处理  {}".format(goods_no))
                # try:
                if self.deal_goods_pic(goods_no, goods_no_path):
                    # 移动文件到已完成
                    # dest = "{}\{}\{}".format(self.is_deal_dir, group_folders, goods_no)
                    # if os.path.exists(dest):
                    #     self.show_info("{} 文件夹在目标目录已存在".format(goods_no))
                    # else:
                    #     shutil.move(goods_no_path, dest)
                    self.show_info("{} 上传成功".format(goods_no))
                else:
                    self.show_info("{} 处理失败".format(goods_no))
                    error_data.append(goods_no)
                    pass
                # except BaseException as e:
                #     self.show_info("上传异常：{}，{}".format(goods_no, e))
                #     raise UnicornException("上传异常：{}，{}".format(goods_no, e))
                # n += 1
                # self.show_info({"type": "show_p",
                #                 "data": int(n * 100 / total_num)})

        self.show_info("========已结束========== ")
        if error_data:
            self.show_info("以下编号/款号处理失败")
            error_msg = ""
            for data in error_data:
                self.show_info("{}".format(data))
                error_msg += data+"\n"
            raise UnicornException(f"以下编号/款号处理失败\n{error_msg}")
        # self.show_info({"type": "change_state",
        #                 "data": 2})

    def deal_goods_pic(self, goods_no, goods_no_path):
        """
        两种模式：货号模式、编号模式
        :param goods_no:
        :param goods_no_path:
        :return:
        """
        print("==========开始上传系统=============")

        s = time.time()

        self.show_info("{} 开始上传 ".format(goods_no))

        if "NUM" in goods_no.upper():
            mode = "编号"
        else:
            mode = "货号"

        # 校验所有编号是否存在，是否是同个款
        _numbers = []
        if mode == "编号":
            _numbers.append(goods_no)

        self.goods_no_data[goods_no] = {}
        # 收集该款号下可能存在的货号或编号
        files = os.listdir(goods_no_path)
        if "details" not in files:
            self.show_info("{} 缺少details 文件夹".format(goods_no, ))
            raise UnicornException("{} 缺少details 文件夹".format(goods_no))
            return False
        for f in files:
            f_path = "{}\{}".format(goods_no_path, f)
            if os.path.isdir(f_path):
                if "details" != f and "货号素材" not in f and "main" not in f and "拼接图" not in f:
                    if not self.is_goods_art_dir(f, goods_no):
                        self.show_info("{} {} 疑似不是货号".format(goods_no, f))
                        # return False
                        continue
                    else:
                        _numbers.append(f)
                if "货号素材" in f:
                    if "_" not in f:
                        self.show_info("{} 货号素材文件夹 格式错误".format(goods_no))
                        raise UnicornException("{} 货号素材文件夹 格式错误".format(goods_no))
                        return False

        # 校验所有编号是否存在，是否是同个款
        if mode == "编号":
            _numbers = [x.replace("KNUM", "").replace("NUM", "") for x in _numbers]
            _numbers = list(set(_numbers))
            goods_number_data = self.data_mode_upload_pic.get_goods_art_no_info(numbers_list=_numbers)

        else:
            if len(_numbers) == 0:
                _numbers = self.config_data["goods_art_nos"]
            goods_number_data = self.data_mode_upload_pic.get_goods_art_no_info(goods_art_list=_numbers)

        t = True
        for num in _numbers:
            if num not in goods_number_data:
                t = False
                if mode == "编号":
                    self.show_info("{} 编号在系统中不存在".format(num))
                else:
                    self.show_info("{} 货号在系统中不存在".format(num))
            else:
                if self.config_data["upload_is_pass"]:
                    if self.data_mode_upload_pic.check_is_uploaded(num):
                        t = False
                        self.show_info("{} 货号在系统已有详情页，已跳过".format(num))
                        return True

        if not t:
            return False
        print("goods_number_data", goods_number_data)
        _ = set([goods_number_data[x]["款号"] for x in goods_number_data])
        if len(_) != 1:
            self.show_info("{} 存在多个不同的款号".format(_))
            raise UnicornException("{} 存在多个不同的款号".format(_))
            return False

        # 重新定义款号
        goods_no = _.pop()

        # 上传所有图片
        self.pic_data = {}
        ignore_text = ["main", "拼接图", "货号素材"]
        _Type = [
            ".png",
            ".PNG",
            ".jpg",
            ".JPG",
            ".gif",
            ".GIF",
            ".webp",
            ".WEBP",
            ".AVIF",
            ".avif",
        ]
        for dirpath, dirnames, filenames in os.walk(goods_no_path):
            for file in filenames:
                if os.path.splitext(file)[1] in _Type:
                    # 获取当前路径的文件夹名称
                    f_path = dirpath + '/' + file
                    f = True
                    for i in ignore_text:
                        if i in f_path:
                            f = False
                            break
                    if f:
                        print(f_path)
                        f_path = f_path.replace("\\", "/")
                        self.pic_data[f_path] = {"url": ""}
        print("上传完成......................!!!!!!!!!!!!!!!!!!!")
        # with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
        for key in self.pic_data:
                if "货号素材" in key:
                    # 货号素材图不上传
                    is_resize = False
                    continue
                else:
                    is_resize = True
                # executor.submit(self.to_upload_pic, file_path=key, is_resize=is_resize)
                self.to_upload_pic(file_path=key, is_resize=is_resize)
        for key in self.pic_data:
            if "货号素材" in key:
                is_resize = False
                continue

            if not self.pic_data[key]["url"]:
                self.show_info("{} {} 图片未上传完成".format(key, goods_no))
                raise UnicornException("{} {} 图片未上传完成".format(key, goods_no))

        up_data = {"goods_art_no": [],
                   "details": [],
                   "goods_no": [],
                   "goods_art_no_material": []
                   }

        details_index = 0
        goods_no_index = 0
        # 款号转换
        # files 为当前款下的所有文件或文件夹
        for f in files:
            f_path = "{}\{}".format(goods_no_path, f)
            f_path = f_path.replace("\\", "/")
            # 如果为文件夹则
            if os.path.isdir(f_path):
                if "details" == f:
                    # 处理详情图
                    for pic in os.listdir(f_path):
                        pic_path = "{}\{}".format(f_path, pic)
                        pic_path = pic_path.replace("\\", "/")

                        details_index += 1
                        data = {
                            "index": details_index,
                            "name": goods_no,
                            "number": goods_no,
                            "status": "success",
                            "type": "2",  # 2 为详情图
                            "uid": "",
                            "url": self.pic_data[pic_path]["url"],
                        }
                        up_data["details"].append(data)
                    pass
                elif "货号素材" in f:
                    continue
                    x = f.split("_")[0]
                    if mode == "编号":
                        x = f.replace("NUM", "")
                        x = x.replace("_货号素材", "")
                        goods_art_no = goods_number_data[x]["商品货号"]
                    else:
                        goods_art_no = x
                    n = 0
                    for pic in os.listdir(f_path):
                        pic_path = "{}\{}".format(f_path, pic)
                        pic_path = pic_path.replace("\\", "/")
                        n += 1
                        data = {
                            "index": n,
                            "name": goods_art_no,
                            "number": goods_art_no,
                            "status": "success",
                            "type": "3",
                            "uid": "",
                            "url": self.pic_data[pic_path]["url"],
                        }
                        up_data["goods_art_no_material"].append(data)
                else:
                    if "拼接图" in f:
                        continue
                    if "main" in f:
                        continue

                    # 处理货号图
                    if mode == "编号":
                        x = f.replace("NUM", "")
                        goods_art_no = goods_number_data[x]["商品货号"]
                    else:
                        goods_art_no = f

                    for pic in os.listdir(f_path):
                        pic_path = "{}\{}".format(f_path, pic)
                        pic_path = pic_path.replace("\\", "/")
                        data = {
                            "index": 1,
                            "name": goods_art_no,
                            "number": goods_art_no,
                            "status": "success",
                            "type": "0",  # 0为货号图
                            "uid": "",
                            "url": self.pic_data[pic_path]["url"],
                        }
                        up_data["goods_art_no"].append(data)
                        break
            else:
                # 处理款号图
                goods_no_index += 1
                data = {
                    "index": goods_no_index,
                    "name": goods_no,
                    "number": goods_no,
                    "status": "success",
                    "type": "1",
                    "uid": "",
                    "url": self.pic_data[f_path]["url"],
                }
                up_data["goods_no"].append(data)
                pass

        # -----------上传数据-----------------
        # print(up_data["goods_no"])
        # print(up_data["goods_art_no_material"])
        # print(up_data["details"])

        # 上传图片
        for key, value in up_data.items():
            if value:
                if not self.data_mode_upload_pic.upload_pic_list_data(data={"images": value}):
                    self.show_info("{} {}上传错误".format(goods_no, key))
                    raise UnicornException("{} {}上传错误".format(goods_no, key))
                    return False

        print("---{}  {} 完成".format(goods_no, time.time() - s))
        return True

    def to_upload_pic(self, file_path, is_resize=True):
        file_name = os.path.split(file_path)[1]
        e = os.path.splitext(file_name)[1][1:]

        im = Picture(file_path)
        if im.x > 1200:
            im.resize(width=1200)

        # print(file_name, e)
        # if e == "png":
        #     im.im.show()
        # return
        _ = {"jpg": "JPEG",
             "JPG": "JPEG",
             "JPEG": "JPEG",
             "jpeg": "JPEG",
             "png": "PNG",
             "PNG": "PNG", }
        e = _[e]
        image_io = im.save_to_io(e)
        # if is_resize:
        #     im = Picture(file_path)
        #     if im.x > 1200:
        #         im.resize(width=1200)
        #     image_io = im.save_to_io()
        #     e = "JPEG"
        # else:
        #     file_name = os.path.split(file_path)[1]
        #     e = os.path.splitext(file_name)[0][1:]
        #     image_io = open(file_path, 'rb')

        # image_io = open(file_path, 'rb')

        # self.lock.acquire()
        # self.pic_data[file_path]["url"] = "1111"
        # self.lock.release()

        # return
        goods_data = {"file_path": os.path.split(file_path)[1],
                      "image_io": image_io,
                      "e": e
                      }

        url = self.data_mode_upload_pic.upload_pic(goods_data=goods_data)
        self.lock.acquire()
        self.pic_data[file_path]["url"] = url
        self.lock.release()

    def is_goods_art_dir(self, file, goods_no):
        if goods_no in file:
            return True
        # 判断是不是货号文件夹
        _r_text = re.findall("[a-zA-Z0-9]+", file)
        if _r_text:
            # print(_r_text)
            if _r_text[0] != file:
                # 文件夹中包含有非字母或数字判断不是货号
                return False
            else:
                return True
        else:
            # 非字母和数字 判断为非货号
            return False

    def show_info(self, text: str):
        # self.show_progress_detail_sign.emit(text)
        # self.windows.show_progress_detail(text)
        print("upload_pic=====>", text)

    def show_text_browser(self, text):
        pass

    def state_change(self, to_state: int):
        self.state = to_state


class Picture:

    def __init__(self, in_path):
        self.im = Image.open(in_path)
        self.x, self.y = self.im.size
        # print(self.x, self.y)

    def resize(self, width):
        re_x = int(width)
        re_y = int(self.y * re_x / self.x)
        self.im = self.im.resize((re_x, re_y), Image.Resampling.LANCZOS)
        self.x, self.y = self.im.size

    def save_to_io(self, format):
        img = BytesIO()
        self.im.save(img, format=format)  # format: PNG or JPEG
        img.seek(0)  # rewind to the start
        return img
