from time import sleep

import axipy
from PySide2.QtCore import QObject, Signal
from PySide2.QtWidgets import QApplication
from axipy import provider_manager, data_manager, Notifications, Version
import axipy
from PySide2.QtCore import QCoreApplication



name_row_id="id___num_zx"
def close(data_object: axipy.DataObject) -> None:
    from axipy.cpp_core_dp import ShadowTransactionalTable as _ShadowTransactionalTable
    from axipy.cpp_render import ShadowCosmeticTable as _ShadowCosmeticTable
    if isinstance(data_object._shadow, _ShadowCosmeticTable):
        raise RuntimeError("It's not allowed to close cosmetic table.")

    if (
            isinstance(data_object, axipy.Table) and
            not isinstance(data_object, axipy.QueryTable) and
            isinstance(data_object._shadow, _ShadowTransactionalTable) and
            data_object.is_temporary and
            data_object.is_editable
    ):
        data_object.rollback()

    data_object._shadow.closeRequest()
    data_object._shadow = None
    QCoreApplication.processEvents()
def closeTable(table):
    if Version.segments()[0]>6:
        table.close()
        return
    close(table)

def getListAtt(table,name_table=None,obj_geo=True):
    list_field=[]
    for att in table.schema:
        if name_table is None:
            list_field.append(table.name+"."+att.name)
        else:
            list_field.append(name_table + "." + att.name)
    if obj_geo:
        if name_table is None:
            list_field.append("style")
            list_field.append("obj")
        else:
            list_field.append(name_table + ".style")
            list_field.append(name_table + ".obj")

    return list_field
class DelDoubleRow(QObject):
    updateProcess = Signal(float)
    updateFormatProgressBar = Signal(str)
    finished = Signal(int)

    def __init__(self, parent_cls):
        super(DelDoubleRow, self).__init__()
        self.__parent_cls = parent_cls

        self.__old_val_progress_local = 0
        self.__out_path=None
    def setParametrs(self,params):
        self.__params=params
    def __process_callback(self, complete_main):

        if self.__cancelProcess:
            return 0
        cur_progress_int = int(complete_main * 100 + 0.5)
        if cur_progress_int>self.__old_val_progress_local:
                self.__old_val_progress_local = cur_progress_int
                self.updateProcess.emit(complete_main * 100)
        #time.sleep(0.001)
        # self.__parent.window.pr_bar.setValue(complete*100)
        # print(complete*100)
        return 1
    def __isCancel(self):
        #print("Cancel")
        self.__cancelProcess=True
        import time
        time.sleep(0.0001)
        QApplication.processEvents()

    def setCancel(self):
        #print("Cancel")
        self.__cancelProcess = True
    @property
    def IsCancel(self):
        return self.__cancelProcess
    @property
    def PathResultFile(self):
        return self.__out_path
    def run(self):
        all_steps=5
        id_step=0
        self.__cancelProcess = False
        self.__list_query_tab=[]
        table_src=data_manager.find(self.__params['table'])
        self.updateFormatProgressBar.emit("Поиск числа дублей .. %p%")
        is_ok = self.__process_callback(id_step/all_steps)
        ''' '''
        sql_query_first="Select rowid as "+name_row_id+",* from "+table_src.name
        print(sql_query_first)
        query_row_id = data_manager.query_hidden(sql_query_first)
        print("end run sql")
        self.__list_query_tab.append(query_row_id)
        id_step=id_step+1
        print("Step 1")
        is_ok = self.__process_callback(id_step / all_steps)
        if is_ok == 0:
            for query in self.__list_query_tab:
                #query.close()
                closeTable(query)

            self.updateProcess.emit(100)
            self.finished.emit(100)
            return
        name_by_group = ','.join(self.__params['list_fields'])
        sql_group="Select "+name_row_id+",Count(*) as cnt From " + query_row_id.name + " group by " + name_by_group
        print(sql_group)
        query_group = data_manager.query_hidden(sql_group)
        self.__list_query_tab.append(query_group)
        ''' Проверяем есть ли дубли'''
        sql_double="Select * from "+query_group.name+" where cnt>1"
        id_step = id_step + 1
        is_ok = self.__process_callback(id_step / all_steps)
        if is_ok == 0:
            for query in self.__list_query_tab:
                #query.close()
                closeTable(query)

            self.updateProcess.emit(100)
            self.finished.emit(100)
            return
        print(sql_double)
        query_group_double=data_manager.query_hidden(sql_double)
        self.__list_query_tab.append(query_group_double)
        if query_group_double.count()==0:
            self.__cancelProcess = True
            for query in self.__list_query_tab:
                #query.close()
                closeTable(query)
            Notifications.push('Предупреждение', " Таблица не содержит дублей", Notifications.Warning)
            self.updateProcess.emit(100)
            self.finished.emit(100)
            return
        id_step = id_step + 1
        is_ok = self.__process_callback(id_step / all_steps)
        if is_ok == 0:
            for query in self.__list_query_tab:
                #query.close()
                closeTable(query)

            self.updateProcess.emit(100)
            self.finished.emit(100)
            return
        list_out_fields = getListAtt(table_src, query_row_id.name)
        sql_join = "select " + ','.join(
            list_out_fields) + " from " +query_row_id.name + "," + query_group.name + " where " + query_row_id.name + "."+name_row_id+"==" +query_group.name + "."+name_row_id + " order by " + query_row_id.name + "."+name_row_id
        if is_ok == 0:
            for query in self.__list_query_tab:
                #query.close()
                closeTable(query)

            self.updateProcess.emit(100)
            self.finished.emit(100)
            return
        print(sql_join)
        query_join = data_manager.query_hidden(sql_join)
        #query_join = data_manager.query(sql_join)
        self.__list_query_tab.append(query_join)
        id_step = id_step + 1
        is_ok = self.__process_callback(id_step / all_steps)
        if is_ok == 0:
            for query in self.__list_query_tab:
                #query.close()
                closeTable(query)

            self.updateProcess.emit(100)
            self.finished.emit(100)
            return
        self.updateFormatProgressBar.emit("Сохраняем таблицу .. %p%")
        dest = provider_manager.tab.get_destination(self.__params['file_dest'], query_join.schema)
        dest.export_from_table(query_join, copy_schema=True)
        count_res=query_join.count()
        count_source=table_src.count()
        delta=count_source-count_res
        Notifications.push('Удаление дублирущихся записей ', " Удалено " + str(delta),
                           Notifications.Information)
        for query in self.__list_query_tab:
            #query.close()
            closeTable(query)
        self.__out_path=self.__params['file_dest']
        self.updateProcess.emit(100)
        self.finished.emit(100)
        return
    def run_test(self):
        self.__cancelProcess=False
        self.updateFormatProgressBar.emit("Поиск числа дублей .. %p%")
        for i in range(100):
            print(i)
            is_ok = self.__process_callback(i / 100)
            if is_ok == 0:
                break
            sleep(0.3)
        self.finished.emit(100)

    def run_slow(self):
        self.__cancelProcess = False
        try:
            self.__parent_cls.disconnect(self.__isCancel)
        except:
            pass
        self.updateProcess.emit(0)
        self.__parent_cls.cancelProcess.connect(self.__isCancel)
        self.__cancelProcess = False
        table_src=data_manager.find(self.__params['table'])
        self.updateFormatProgressBar.emit("Поиск числа дублей .. %p%")
        sql_first="Select rowid as "+name_row_id+",* from "+table_src.name
        query_row_id = data_manager.query_hidden(sql_first)
        if query_row_id.count()==0:
            query_row_id.close()
            Notifications.push('Предупреждение', " Таблица пустая", Notifications.Warning)
            self.updateProcess.emit(100)
            self.finished.emit(100)
        name_by_group = ','.join(self.__params['list_fields'])
        sql_second = "Select *,Count(*) as cnt From " + query_row_id.name + " group by " + name_by_group + " HAVING cnt>1 "
        query_row_double=data_manager.query_hidden(sql_second)
        count_double=query_row_double.count()
        if count_double==0:
            query_row_id.close()
            query_row_double.close()
            Notifications.push('Предупреждение', " Таблица не содержит дублей", Notifications.Warning)
            self.updateProcess.emit(100)
            self.finished.emit(100)
        sql_order = "Select * from " + query_row_double.name + " order by "+name_row_id+" DESC"
        query_order=data_manager.query_hidden(sql_order)
        self.updateFormatProgressBar.emit("Удаление дублей .. %p%")
        Notifications.push('Удаление дублей', "Найдено дублей "+str(count_double), Notifications.Warning)
        count_del_row=0
        for i, item in enumerate(query_order.items()):
            is_ok = self.__process_callback(i / count_double)
            if is_ok == 0:
                break
            cur_id = item[name_row_id]

            sql_temp_query = "Select * from " + query_row_id.name + " where "+name_row_id+"=" + str(cur_id)
            sql_temp_query = "(" + sql_temp_query + ")"
            cur_sql = "select " +query_row_id.name + ".* from " + query_row_id.name + "," + sql_temp_query + " as Query_zzz " + " where " + query_row_id.name + "."+name_row_id+"<>" + str(
                cur_id) + " and " + query_row_id.name + ".obj=" + "Query_zzz.obj"
            query_cur=data_manager.query_hidden(cur_sql,axipy.da.TypeSqlDialect.sqlite)
            '''
            list_ids = []
            for item_del in query_cur.items():
                list_ids.append(item_del.id)
            if len(list_ids) > 0:
                query_cur.remove(list_ids)
            '''
            query_cur.close()
            count_del_row=count_del_row+1
        query_row_id.close()
        query_row_double.close()
        query_order.close()
        Notifications.push('Удаление дублирущихся записей ', " Удалено "+str(count_del_row), Notifications.Information)
        self.updateProcess.emit(100)
        self.finished.emit(100)
        








