import os.path
import random
import shutil
import time

from utils.utils_func import get_images, move_elements_inplace, check_path, get_cutout_image_info


class GoodsArtImageList():
    # select_clearn_all_sign = Signal(str)

    def __init__(self, goods_art_no_folder_path, parent=None, windows=None,
                 label_color="green", is_goods_art_no_folder=True):
        super().__init__(parent)
        # self.ui = Ui_Form()
        # self.ui.setupUi(self)
        self.windows = windows

        # parent: QWidget
        self.parent = parent
        self.has_selected = False
        # self.ui.label_5.setStyleSheet("background-color: {};".format(label_color))

        self.goods_art_no_folder_path = goods_art_no_folder_path
        self.folder_name = os.path.split(goods_art_no_folder_path)[1]
        self.is_goods_art_no_folder = is_goods_art_no_folder
        if is_goods_art_no_folder:
            self.original_path = "{}/原始图".format(goods_art_no_folder_path)
            self.cut_out_path = "{}/已扣图".format(goods_art_no_folder_path)
        else:
            self.original_path = goods_art_no_folder_path
            self.cut_out_path = ""
            # self.ui.del_folder.hide()

        self.drag_start_position = None
        # self.ui.widget.setMinimumSize(300, 200)
        self.image_data_list = []
        self.init_data()
        # self.show_list()
        # self.init()
        # self.show()

    def init(self):
        self.setAcceptDrops(True)
        self.ui.widget.setAcceptDrops(True)
        self.ui.widget.dropEvent = self.list_dropEvent
        self.ui.widget.dragEnterEvent = self.list_dragEnterEvent
        self.ui.widget.dragMoveEvent = self.list_dragMoveEvent
        self.ui.del_folder.mousePressEvent = self.del_folder
        self.ui.open_folder.mousePressEvent = self.open_folder

    # 删除文件夹
    # def del_folder(self, *args):
    #     if not self.is_goods_art_no_folder:
    #         return
    #     a = QMessageBox.question(self, '确认', '是否删除该文件夹',
    #                              QMessageBox.Yes | QMessageBox.No)
    #     if a != QMessageBox.Yes:
    #         return

    #     try:
    #         shutil.rmtree(self.goods_art_no_folder_path)
    #     except BaseException as e:
    #         print("删除文件夹失败", e)
    #     self.hide()
    #     self.deleteLater()

    # 打开本地文件夹
    def open_folder(self, *args):
        if os.path.exists(self.original_path):
            os.startfile(self.original_path)

    def set_new_parent(self, parent):
        self.parent = parent
        self.setParent(parent)

    # def resizeEvent(self, event: QResizeEvent):
    #     # print(self.size())
    #     self.show_list()
    #     # 当窗口大小发生变化时，更新标签文本
    #     # 调用父类的resizeEvent以确保其他必要的调整也被执行
    #     super().resizeEvent(event)

    # 刷新展示列表
    # def show_list(self):
    #     self.ui.label.setText("文件夹:{}".format(self.folder_name))
    #     if not self.image_data_list:
    #         self.ui.widget.setMinimumHeight(20)
    #         self.ui.widget.setMaximumHeight(20)
    #         return
    #     x, y = 0, 5
    #     total_len = len(self.image_data_list)
    #     for index, image_label in enumerate(self.image_data_list):
    #         image_label: ImageLabel
    #         image_label.image_index = index
    #         image_label.move(x, y)
    #         image_label.show_text()
    #         image_label.show()
    #         x += image_label.width() + 5
    #         if x + image_label.width() > self.ui.widget.width():
    #             x = 0
    #             if total_len != index + 1:
    #                 y += image_label.height() + 5
    #     self.ui.widget.setMaximumHeight(y + image_label.height())
    #     self.ui.widget.setMinimumHeight(y + image_label.height())
    #     self.setMaximumHeight(y + image_label.height() + self.ui.label.height())

    #     # 刷新界面命令
    #     QApplication.processEvents()

    # 初始化数据
    def init_data(self):
        # for index, image_data in enumerate(get_images(self.original_path)):
        #     image_label = ImageLabel(text="",
        #                              image_index=index,
        #                              image_path=image_data["file_path"],
        #                              image_name=image_data["file_name"],
        #                              root_path=self.original_path,
        #                              is_goods_list=True,
        #                              parent=self.ui.widget,
        #                              windows=self,
        #                              top_windows=self.windows
        #                              )
        #     self.reconnect_sign(image_label, self)
        #     self.image_data_list.append(image_label)
        pass
            # # 刷新界面命令
            # QApplication.processEvents()

    # 重新与当前父组件绑定信号
    def reconnect_sign(self, image_label, windows):
        try:
            image_label.select_clearn_all_sign.disconnect()
            image_label.selected_sign.disconnect()
            image_label.drop_sign.disconnect()
            image_label.drop_from_sign.disconnect()
            image_label.delete_image_sign.disconnect()
        except:
            pass  # 如果没有连接则忽略错误

        image_label.select_clearn_all_sign.connect(windows.clearn_all_label_select)
        image_label.selected_sign.connect(windows.set_selected)
        image_label.drop_sign.connect(windows.deal_image_label_to)
        image_label.drop_from_sign.connect(windows.deal_image_label_from)
        image_label.delete_image_sign.connect(windows.delete_image_items)

    def set_image_label_parent(self, image_label):
        image_label.set_new_parent(self.ui.widget)

    # 批量删除图片
    def delete_image_items(self, image_index_list: list):
        image_index_list.sort(reverse=True)
        # for image_index in image_index_list:
        #     image_label: ImageLabel
        #     image_label = self.image_data_list.pop(image_index)
        #     image_label.del_image()
        #     image_label.deleteLater()
        # self.show_list()

    # 设置有选择
    def set_selected(self):
        self.has_selected = True
        self.select_clearn_all_sign.emit(self.original_path)

    # 清除所有已选
    def clearn_all_label_select(self, flag=False):
        _f = False
        if flag:
            _f = True
        else:
            if self.has_selected:
                _f = True

        if _f:
            for image_label in self.image_data_list:
                # image_label: ImageLabel
                # if image_label.selected:
                image_label.set_selected(False)

    # 手动排序
    def re_sort_by_manual(self):
        # 重新排序
        pass

    # 粘贴到事件;处理同文件夹内容
    def deal_image_label_to(self, data, is_real_same_folder=False):
        is_same_folder = data["is_same_folder"]
        print(data)
        # 来自同文件夹
        if is_same_folder:
            target_index = data["to_image_index"]
            indices = data["from_image_index_list"]
            if target_index in indices:
                return
            move_elements_inplace(lst=self.image_data_list, indices=indices, target_index=target_index,
                                  is_real_same_folder=is_real_same_folder)
            # 刷新文件名称
            self.rename_image(target=self)
            self.show_list()

    # 处理不同文件夹事件
    def deal_image_label_from(self, data):
        # 如果是来源于不同的文件夹，则需要处理这个。
        """
        从原列表进行剔除
        添加到新列表，并插入到指定位置
        """
        is_same_folder = data["is_same_folder"]
        if is_same_folder is False:
            from_image_index_list = data["from_image_index_list"]
            from_image_index_list: list
            from_image_index_list.sort(reverse=True)
            to_source = data["to_source"]
            from_source = data["from_source"]
            to_source_len_image = len(to_source.image_data_list) - 1
            to_image_index = data["to_image_index"]
            indices = []
            # 从末尾进行剔除，并添加到另外一个列表
            temp = []
            for from_index in from_image_index_list:
                image_label = from_source.image_data_list.pop(from_index)
                temp.append(image_label)

            # 倒序处理
            for image_label in temp[::-1]:
                to_source_len_image += 1
                to_source.image_data_list.append(image_label)
                to_source.set_image_label_parent(image_label)
                to_source.set_image_label_windows(image_label, to_source)
                to_source.reconnect_sign(image_label, to_source)  # 重新绑定信号

                # 设定父类
                image_label.windows = to_source
                indices.append(to_source_len_image)
            # 目标文件夹处理
            move_elements_inplace(lst=to_source.image_data_list, indices=indices, target_index=to_image_index)
            self.dealMoveImage(to_source=to_source)

            to_source.show_list()
            # 刷新来源文件夹
            from_source.show_list()

            # 全部重命名
            self.rename_image(target=to_source)

            # 取消已选数据
            to_source.has_selected = True
            from_source.has_selected = True

            to_source.clearn_all_label_select(flag=True)
            from_source.clearn_all_label_select(flag=True)

    def set_image_label_windows(self, image_label, windows):
        image_label.set_image_label_windows(windows)

    def dealMoveImage_beifen(self, to_source):
        '''
        从其他文件夹复制移动图片
         参数例 sources = ['D:\\phpstudy_pro\\WWW\\auto_photo\\output\\2024-11-18/2222222/原始图/abc.jpg', D:\\phpstudy_pro\\WWW\\auto_photo\\output\\2024-11-18/2222222/原始图/ddd.jpg]
            target = 'D:\\phpstudy_pro\\WWW\\auto_photo\\output\\2024-11-18/2222222/原始图'
        '''
        target = to_source.original_path
        targetParent, _ = os.path.split(target)
        for imageLabel in to_source.image_data_list:
            if imageLabel.root_path == target:
                continue
            path, sourceFile = os.path.split(imageLabel.image_path)
            sourceFileName, file_extension = os.path.splitext(sourceFile)
            parentPath, _ = os.path.split(path)
            sourceCutPath = '{}/原始图_已抠图/{}.png'.format(parentPath, sourceFileName)
            newFileName = str(time.time()) + str(random.randint(1000000, 9999999))
            targetName = target + '/' + newFileName + file_extension

            if os.path.exists(imageLabel.image_path):
                shutil.move(imageLabel.image_path, targetName)
                self.upImageLabel(item=imageLabel, image_name=newFileName, image_path=targetName)
                if os.path.exists(sourceCutPath) and os.path.exists(
                        "{}/原始图_已抠图".format(targetParent)) and os.path.isdir("{}/原始图_已抠图".format(targetParent)):
                    cutTargetPath = '{}/原始图_已抠图/{}.png'.format(targetParent, newFileName)
                    shutil.move(sourceCutPath, cutTargetPath)

        self.rename_image(to_source)

    def dealMoveImage(self, to_source):
        '''
        从其他文件夹复制移动图片
         参数例 sources = ['D:\\phpstudy_pro\\WWW\\auto_photo\\output\\2024-11-18/2222222/原始图/abc.jpg', D:\\phpstudy_pro\\WWW\\auto_photo\\output\\2024-11-18/2222222/原始图/ddd.jpg]
            target = 'D:\\phpstudy_pro\\WWW\\auto_photo\\output\\2024-11-18/2222222/原始图'
        '''
        """
        步骤：
        1、获取来源的图片与已扣图图片
        2、随机进行命名，（包括已扣图）
        3、移动
        以上过程需要考虑是否存在对应路径或图片
        """
        # original_path 为原始图路径
        target_original_path = to_source.original_path
        # target_original_root_path 为目标的原始图路径
        target_goods_art_no_root_path, _ = os.path.split(target_original_path)

        # target_cutout_root_path 为目标的原始图_已扣图路径
        target_cutout_root_path = None
        if "原始图" == target_original_path[-3:]:
            target_cutout_root_path = target_original_path[:-3] + "原始图_已抠图"
            if not os.path.exists(target_cutout_root_path):
                # 创建一个已扣图路径
                check_path(target_cutout_root_path)

        # 轮询移动每个文件
        for imageLabel in to_source.image_data_list:
            # 来源为当前原图片文件夹，则忽略
            if imageLabel.root_path == target_original_path:
                continue

            image_info_data = get_cutout_image_info(imageLabel.image_path)
            if image_info_data is None:
                continue

            # 创建一个随机名称
            new_file_name = str(int(time.time()) + random.randint(10000, 59999))
            target_image_path = "{}/{}{}".format(target_original_path, new_file_name,
                                                 image_info_data["source_file_extension"])
            # 移动原始图
            shutil.move(image_info_data["source_image_path"], target_image_path)
            self.upImageLabel(item=imageLabel, image_name=new_file_name, image_path=target_image_path)

            # 移动已扣图图片
            print(image_info_data)
            if target_cutout_root_path is None:
                # 如果不存在已扣图文件夹，但是图片又存在，则需要进行文件删除
                if image_info_data["cutout_image_path"]:
                    if os.path.exists(image_info_data["cutout_image_path"]):
                        os.remove(image_info_data["cutout_image_path"])
                continue

            if image_info_data["cutout_image_path"] is not None:
                # 移动原始图
                target_cutout_image_path = "{}/{}{}".format(target_cutout_root_path, new_file_name,
                                                            image_info_data["cutout_image_file_extension"])
                print("target_cutout_image_path", target_cutout_image_path)

                shutil.move(image_info_data["cutout_image_path"], target_cutout_image_path)

        # self.rename_image(to_source)

    def rename_image_beifen(self, target):
        """
         重新排序，重新命名图片
        """
        target: GoodsArtImageList

        path, _ = os.path.split(target.original_path)
        _, artno = os.path.split(path)

        imageNames = []
        for index, item in enumerate(target.image_data_list):
            imageNames.append(item.image_name)
            _, image_extend = os.path.splitext(item.image_path)
            targetPath = "{}/copy_tmp（{}）{}".format(item.root_path, index, image_extend)
            if os.path.exists(item.image_path):
                shutil.move(item.image_path, targetPath)
                imageName = 'copy_tmp（{}）'.format(index)
                self.upImageLabel(item=item, image_name=imageName, image_path=targetPath)

        for index, item in enumerate(target.image_data_list):
            _, image_extend = os.path.splitext(item.image_path)
            imageName = '{}（{}）'.format(artno, index + 1)
            targetPath = "{}/{}{}".format(item.root_path, imageName, image_extend)
            if os.path.exists(item.image_path):
                shutil.move(item.image_path, targetPath)
                self.upImageLabel(item=item, image_name=imageName, image_path=targetPath)

        self.dealCutImage(target, imageNames)

    def rename_image_by_prefix(self, target, new_file_prefix):
        pass
        # for image_label in target.image_data_list:
        #     image_label: ImageLabel
        #     if not os.path.exists(image_label.image_path):
        #         continue

        #     if os.path.isdir(image_label.image_path):
        #         continue

        #     # 原始图信息
        #     original_path, original_file = os.path.split(image_label.image_path)
        #     original_file_name, original_file_extension = os.path.splitext(original_file)
        #     new_file_name = "{}（{}）".format(new_file_prefix, image_label.image_index + 11)
        #     new_original_file_name = "{}/{}{}".format(original_path,
        #                                               new_file_name,
        #                                               original_file_extension
        #                                               )
        #     # 重命名
        #     os.rename(image_label.image_path, new_original_file_name)
        #     self.upImageLabel(item=image_label, image_name=new_file_name, image_path=new_original_file_name)

        #     # 处理已扣图的重命名
        #     if original_path[-3:] != "原始图":
        #         continue
        #     cutout_original_path = original_path[:-3] + "原始图_已抠图"
        #     cutout_image_path = "{}/{}.png".format(cutout_original_path, original_file_name)
        #     if not os.path.exists(cutout_image_path):
        #         continue

        #     new_cutout_file_name = "{}/{}.png".format(cutout_original_path,
        #                                               new_file_name,
        #                                               )
        #     # 重命名
        #     os.rename(cutout_image_path, new_cutout_file_name)

    def rename_image(self, target):
        """
         重新排序，重新命名图片
        """
        """
        步骤：
        1、先统一修改一个随机名称str(random.randint(60000, 99999))
        2、再还原为指定名称
        以上已扣图需要同步修改
        """

        target: GoodsArtImageList
        # original_path 为原始图路径
        # print("398            rename_image          ")
        new_file_prefix = str(random.randint(60000, 99999))
        self.rename_image_by_prefix(target, new_file_prefix)
        self.rename_image_by_prefix(target, target.folder_name)

    def dealCutImage(self, target, imageNames):
        path, _ = os.path.split(target.original_path)
        _, artno = os.path.split(path)
        cutout_path = '{}/原始图_已抠图'.format(path)
        if not os.path.exists(cutout_path):
            return None

        cutImages = self.getDirImageList(cutout_path)
        for index, item in enumerate(cutImages):
            if item['image_name'] not in imageNames:
                shutil.move(item['image_path'], '{}/原始图_已抠图/remove{}.png'.format(path, index))

        for index, item in enumerate(imageNames):
            if os.path.exists('{}/原始图_已抠图/{}.png'.format(path, item)):
                shutil.move('{}/原始图_已抠图/{}.png'.format(path, item),
                            '{}/原始图_已抠图/copy_tmp（{}）.png'.format(path, index))
                imageNames[index] = 'copy_tmp（{}）'.format(index)

        for index, item in enumerate(imageNames):
            if os.path.exists('{}/原始图_已抠图/{}.png'.format(path, item)):
                shutil.move('{}/原始图_已抠图/{}.png'.format(path, item),
                            '{}/原始图_已抠图/{}（{}）.png'.format(path, artno, index + 1))

    def upImageLabel(self, item, image_name, image_path):
        item.text = image_name
        item.image_name = image_name
        item.image_path = image_path
        item.root_path, _ = os.path.split(image_path)
        item.show_text()

    def getDirImageList(self, path):
        list = os.listdir(path)
        result = []
        for val in list:
            name, _ = os.path.splitext(val)
            result.append({
                'image_path': '{}/{}'.format(path, val),
                'image_name': name
            })
        return result
        # print(item.image_path)

    # 有且，只有目标粘贴位置才会触发该方法;粘贴到空白位置
    def list_dropEvent(self, event):
        # mime = event.mimeData()
        pass
        # if mime.hasFormat('application/x-draggable-labels'):
        #     return_data = {"is_same_folder": True,
        #                    "from_image_index_list": [],
        #                    "from_source": "",
        #                    "to_image_index": 0,
        #                    "to_source": "",
        #                    }
        #     byte_array = mime.data('application/x-draggable-labels')
        #     stream = QDataStream(byte_array, QIODevice.ReadOnly)
        #     while not stream.atEnd():
        #         image_index = stream.readInt32()
        #         return_data["from_image_index_list"].append(image_index)

        #     from_source = event.source()
        #     return_data["from_source"] = from_source.windows
        #     return_data["to_source"] = self
        #     return_data["to_image_index"] = len(self.image_data_list)  # 添加到末尾

        #     if from_source.windows == self:
        #         return_data["is_same_folder"] = True
        #         print("粘贴到末尾，同文件夹")
        #     else:
        #         return_data["is_same_folder"] = False
        #         print("粘贴到末尾，不同文件夹")

        #     if return_data["is_same_folder"] is False:
        #         # 不同文件夹处理，处理发送到来源文件夹的操作
        #         self.deal_image_label_from(return_data)
        #     else:
        #         # 同文件夹处理，发送粘贴的信号
        #         self.deal_image_label_to(return_data, is_real_same_folder=True)

    def list_dragEnterEvent(self, event):
        event.acceptProposedAction()

    def list_dragMoveEvent(self, event):
        event.acceptProposedAction()
