from PySide2.QtCore import QObject
from axipy import data_manager, TypeSqlDialect
from loguru import logger
import time
from ru_rubtsov_axioma_topo_tools.toolprocessing.add_helper.helper_tab import  TableCacheUpdate
class CalcIntProcent:
    def __init__(self,count):
        self.__last_proc=-1
        self.__count=count
    def getValue(self,curent):
        cur_val=int((curent/self.__count)*100+0.5)
        if cur_val==self.__last_proc:
            return None
        self.__last_proc=cur_val
        return cur_val
def snapGeo(name_table,id_base,id_second,name_row_id,tollerance):
    sql_base="select "+name_row_id+", obj from "+name_table+" where "+name_row_id+"="+str(id_base)
    #print(sql_base)
    query_base=data_manager.query_hidden(sql_base,dialect=TypeSqlDialect.axioma)

    sql_second="select "+name_row_id+",obj from "+name_table+" where "+name_row_id+"="+str(id_second)
    #print(sql_second)
    query_second=data_manager.query_hidden(sql_second,dialect=TypeSqlDialect.axioma)
    sql_sel = "select base."+name_row_id+",Snap(FromAxiGeo(base.obj),FromAxiGeo(second.obj),"+str(tollerance)+") as obj From " + query_base.name + " as base ," + query_second.name + " as second where base."+name_row_id+"<>second."+name_row_id
    #print(sql_sel)
    query=data_manager.query_hidden(sql_sel,dialect=TypeSqlDialect.sqlite)
    fts_sel=list(query.items())
    geo_snap=fts_sel[0].geometry

    #print("Close Query")
    try:
        query_base.close()
        query_second.close()
        query.close()
        #print("Ok Close Query")
    except Exception as ex:
        logger.exception("Error close query")

    #print("end Snap")

    return geo_snap

class SnapPoints(QObject):
    __name_row_id="__id_row__"
    def __init__(self,name_table,tollerance):
        self.__name_tab=name_table
        self.__value_tollerance=tollerance
        self.__list_query=[]

    def run(self,func_call_bac=None):
        if func_call_bac is not None:
            func_call_bac(0)
        sql_rowid="select RowNum() as "+self.__name_row_id+",* from "+self.__name_tab
        print("Main sql:"+sql_rowid)
        query_row_id=data_manager.query_hidden(sql_rowid)
        try:
            count_ft=query_row_id.count()

            cls_procent=CalcIntProcent(count_ft)
            tab_cache=TableCacheUpdate(query_row_id,1000)
            index_ft = 0
            for ft in query_row_id.items():
                index_ft = index_ft+1
                value=cls_procent.getValue(index_ft)
                if value is not None:

                    isCancel=func_call_bac(value)
                    if isCancel:
                        break
                if ft.geometry is None:
                    continue
                id_base = ft[self.__name_row_id]
                sql_intersect = "select base.* From " + query_row_id.name + " as base ,(select * from  " + query_row_id.name + " where "+self.__name_row_id+"=" + str(
                    id_base) + ") as  item where base."+self.__name_row_id+">item."+self.__name_row_id+" and base.obj  Intersects  item.obj "
                query_intersect=data_manager.query(sql_intersect)
                ftsel_update=[]
                for ft_sel in query_intersect.items():
                    id_select=ft_sel[self.__name_row_id]
                    geo_new_base = snapGeo(query_row_id.name, id_base, id_select,self.__name_row_id,self.__value_tollerance)

                    if geo_new_base is not None:
                        ft.geometry = geo_new_base
                        tab_cache.add(ft)


                    geo_new_second = snapGeo(query_row_id.name,id_select, id_base, self.__name_row_id,self.__value_tollerance)

                    if geo_new_second is not None:
                        ft_sel.geometry = geo_new_second
                        ftsel_update.append(ft_sel)
                if len(ftsel_update)>0:
                    pass
                    query_intersect.update(ftsel_update)
                query_intersect.close()

            tab_cache.end(True)
            func_call_bac(100)
            #self.__list_query.append(query_row_id)
        except Exception as ex:
            logger.exception(ex)
        finally:

            query_row_id.close()
    def clearQuery(self):
        if len(self.__list_query)==0:
            return
        for query in self.__list_query:
            query.close()


