import datetime
import os
import time
from pathlib import Path

from PySide2 import QtCore
from PySide2.QtCore import QFile, QObject, QThread
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QWidget, QFileDialog, QDialog, QApplication
from axipy import CoordSystem, ChooseCoordSystemDialog

from rosreestrXml.ui.WidgetStyles import StylesKpt
from rosreestrXml.ui.tools.KPT.kptTools.DbKptDirectory import KptСatalog
from rosreestrXml.ui.tools.importKptProcess import ImportKpT
def findProperties(list_prop,name):
    obj_prop=list(filter(lambda item: item['alias'] == name, list_prop))
    if obj_prop is None or len(obj_prop)==0:
        return None
    return obj_prop[0]

class XmlImportMainForm(QWidget):
    cancelProcess = QtCore.Signal()
    #def __init__(self,properties_kpt, parent=None):
    def __init__(self,  parent=None):
        #self.__properties_kpt=properties_kpt
        super(XmlImportMainForm, self).__init__(parent)
        self.__propreties_style={
	        "type_kpt":[
            {"name": "лесные декларации", "table": "forest_declaration_style", 'enable': True},
		    {"name":"кадастрового плана территории","table":"kpt_11_style",'enable':True},
            {"name": "(устаревший) кадастрового плана территории", "table": "kpt_10_style", 'enable': True},
            {"name": "выписка ЕГРН ", "table": "egrn_style", 'enable': True},
            {"name": "объект незавершенного строительства", "table": "under_construction", 'enable': True},
	                ]
        }
        self.__cs_prj='NonEarth Units "m" '
        self.__cs_axi=CoordSystem.from_prj(self.__cs_prj)
        self.__process=None
        self.__source_path=None
        self.__dialogSource=None
        self.__dialogDest = None
        self.__list_source_files = None
        self.__parentWin = parent

        self.load_ui('mainForm_v3.ui')
        self.__widgetPropertiesStyle=StylesKpt(self.__propreties_style)
        self.ui.verticalLayout_properies.addWidget(self.__widgetPropertiesStyle.ui)
        self.ui.rb_select_source.clicked.connect(self.__select_source_files)
        self.ui.tb_select_save.clicked.connect(self.__select_dest_file)
        self.ui.pb_run.setEnabled(False)
        self.ui.pb_cancel.setEnabled(False)
        self.ui.pb_run.clicked.connect(self.__run)
        self.ui.pb_cancel.clicked.connect(self.__cancel)
        self.ui.tb_select_cs.clicked.connect(self.__change_cs)
        self.ui.lb_cs.setText(self.__cs_axi.name)
    def load_ui(self, name_resource):
        loader = QUiLoader()
        path = os.path.join(os.path.dirname(__file__), name_resource)
        ui_file = QFile(path)
        ui_file.open(QFile.ReadOnly)
        self.ui = loader.load(ui_file, self.__parentWin)
        ui_file.close()
    def __change_cs(self):
        dlg_cs =ChooseCoordSystemDialog( self.__cs_axi)
        if dlg_cs.exec() == QDialog.Accepted:
            self.__cs_axi=dlg_cs.chosenCoordSystem()
            self.ui.lb_cs.setText(self.__cs_axi.name)
    def __select_source_files(self):
        if self.__dialogSource is None:
            self.__dialogSource=QFileDialog(self.ui)
        if self.__source_path is None:
            self.__source_path = str(Path.home())
        self.__dialogSource.setDirectory(self.__source_path)
        self.__dialogSource.setWindowTitle('Выбрать файлы xml')
        self.__dialogSource.setDefaultSuffix("xml")
        self.__dialogSource.setNameFilter("Xml (*.xml);;Zip (*.zip)")
        self.__dialogSource.setFileMode(QFileDialog.ExistingFiles)
        if self.__dialogSource.exec_() == QDialog.Accepted:
            file_full_path = str(self.__dialogSource.selectedFiles()[0])
            list_selected_files=self.__dialogSource.selectedFiles()
            if len(list_selected_files)==1:
                self.ui.ln_edit_source.setText(list_selected_files[0])
            else:
                self.ui.ln_edit_source.setText(str(Path(file_full_path).parent))
            self.ui.ln_edit_source.setCursorPosition(0)
            self.__source_path=str(Path(list_selected_files[0]).parent)
            self.__isOkSelectInputFiles(list_selected_files)
        else:
            self.__list_source_files=None

    def __isOkSelectInputFiles(self,list_files):
        self.__list_source_files=list_files.copy()
        self.ui.pb_run.setEnabled(True)
        ''' Формируем имя выходного файла'''
        if len(self.__list_source_files)==1:
            path_source=Path(self.__list_source_files[0])
            path_out=path_source.parent.joinpath(path_source.stem+".gpkg")

        else:
            ''' Несколько фалов '''
            ''' формируем имя из даты '''
            str_data=datetime.datetime.now().strftime(('%Y_%m_%d_%H_%M_%S'))
            path_source = Path(self.__list_source_files[0])
            path_out = path_source.parent.joinpath(str_data+".gpkg")
        self.ui.ln_path_out_file.setText(str(path_out))

        self.ui.ln_path_out_file.setCursorPosition(0)
        #self.ui.pb_run.setEnabled(True)
        return
    def __select_dest_file(self):
        if self.__dialogDest is None:
            self.__dialogDest=QFileDialog(self.ui)
        path_out=self.ui.ln_path_out_file.text()
        if len(path_out)==0:
            path_out=str(Path.home())
        if not Path(path_out).exists():
            path_out = str(Path.home())
        self.__dialogDest.setDirectory(str(Path(path_out).parent))
        self.__dialogDest.setWindowTitle('Сохранить в ..')
        self.__dialogDest.setDefaultSuffix("gpkg")
        self.__dialogDest.setNameFilter("Gpkg (*.gpkg)")
        self.__dialogDest.setAcceptMode(QFileDialog.AcceptSave)
        selected = self.__dialogDest.exec()
        if not selected:
            return
        file_save_as=self.__dialogDest.selectedFiles()[0]
        self.ui.ln_path_out_file.setText(file_save_as)

        self.ui.ln_path_out_file.setCursorPosition(0)
    def __cancel(self):
        if self.__process is not None:
            self.__process_status = False
            self.cancelProcess.emit()
            self.__process.setCancel()
    def __getPropertyForImport(self):
        properties = {}
        prop_kpt10 = {}

        prop_kpt10['zones'] = {}
        prop_kpt10['zones']['enable'] = True
        prop_kpt10['spatial_data'] = {}
        prop_kpt10['spatial_data']['enable'] = True
        prop_kpt10['parcels'] = {}
        prop_kpt10['parcels']['enable'] = True
        prop_kpt10['bounds'] = {}
        prop_kpt10['bounds']['enable'] = True
        prop_kpt10['realtys'] = {}
        prop_kpt10['realtys']['enable'] = True
        prop_kpt10['oms_points'] = {}
        prop_kpt10['oms_points']['enable'] = True
        prop_kp11 = {}
        prop_kp11['zones'] = {}
        # properties['zones']['style']=mi_style
        prop_kp11['zones']['enable'] = True

        prop_kp11['municipal'] = {}
        # properties['municipal']['style']=mi_style
        prop_kp11['municipal']['enable'] = True
        prop_kp11['spatial'] = {}
        # properties['spatial']['style']=mi_style
        prop_kp11['spatial']['enable'] = True

        prop_kp11['land_building'] = {}
        # properties['land_building']['style']=mi_style
        prop_kp11['land_building']['enable'] = True

        properties['kpt11'] = prop_kp11
        properties['kpt10'] = prop_kpt10
        return properties


    def __getPropertyKpt10(self,db):
        values_db=db.GetPropertiesKpt('kpt_10_style')
        prop_kpt10 = {}
        item_value=findProperties( values_db,'SpatialData')
        prop_kpt10['spatial_data'] = {}
        prop_kpt10['spatial_data']['enable'] = False
        if item_value is None or item_value['enable']==1:
            prop_kpt10['spatial_data']['enable'] = True
        prop_kpt10['parcels'] = {}
        prop_kpt10['parcels']['enable'] = False
        item_value = findProperties( values_db,'Parcels')

        if item_value is None or item_value['enable'] == 1:
            prop_kpt10['parcels']['enable'] = True
        prop_kpt10['realtys'] = {}
        prop_kpt10['realtys']['enable'] = False
        item_value = findProperties( values_db,'ObjectsRealty')

        if item_value is None or item_value['enable'] == 1:
            prop_kpt10['realtys']['enable'] = True
        prop_kpt10['bounds'] = {}
        prop_kpt10['bounds']['enable'] = False
        item_value = findProperties(values_db,'Bounds')

        if item_value is None or item_value['enable'] == 1:
            prop_kpt10['bounds']['enable'] = True
        prop_kpt10['oms_points'] = {}
        prop_kpt10['oms_points']['enable'] = False
        item_value = findProperties( values_db,'OMSPoints')

        if item_value is None or item_value['enable'] == 1:
            prop_kpt10['oms_points']['enable'] = True
        prop_kpt10['zones'] = {}
        prop_kpt10['zones']['enable'] = False
        item_value = findProperties( values_db,'Zones')

        if item_value is None or item_value['enable'] == 1:
            prop_kpt10['zones']['enable'] = True
        item_value = findProperties( values_db,'Building')
        #if item_value is not None and  item_value['enable'] == 0:
        return prop_kpt10
    def __getPropertyKpt11(self,db):
        values_db=db.GetPropertiesKpt('kpt_11_style')
        prop_kpt11 = {}
        item_value=findProperties( values_db,'zone')

        prop_kpt11['zones'] = {}
        prop_kpt11['zones']['enable'] = False
        if item_value is None or item_value['enable']==1:
            prop_kpt11['zones']['enable'] = True
        item_value = findProperties( values_db,'building')
        prop_kpt11['сonstruction_building'] = {}
        prop_kpt11['сonstruction_building']['enable'] = False
        if item_value is None or item_value['enable'] == 1:
            prop_kpt11['сonstruction_building']['enable'] = True
        item_value=findProperties(values_db,"сonstruction")
        if item_value is not None and item_value['enable'] == 1:
            prop_kpt11['сonstruction_building']['enable'] = True
        '''
        if item_value is not None and item_value['enable'] == 1:
            prop_kpt11['land_building']['enable'] = True
        '''
        prop_kpt11['land'] = {}
        prop_kpt11['land']['enable']=False
        item_value = findProperties( values_db,'land')
        if item_value is not None and item_value['enable'] == 1:
            prop_kpt11['land']['enable'] = True
        '''
        item_value = findProperties('bound_kvartal')
        prop_kpt11['land_building'] = {}
        prop_kpt11['land_building']['enable'] = False
        if item_value is None or item_value['enable'] == 1:
            prop_kpt11['land_building']['enable'] = True
        '''
        item_value = findProperties( values_db,'municipal_bound')
        prop_kpt11['municipal'] = {}
        prop_kpt11['municipal']['enable'] = False
        if item_value is None or item_value['enable'] == 1:
            prop_kpt11['municipal']['enable'] = True
        item_value = findProperties( values_db,'bound_kvartal')
        prop_kpt11['spatial'] = {}
        prop_kpt11['spatial']['enable'] = False
        if item_value is None or item_value['enable'] == 1:
            prop_kpt11['spatial']['enable'] = True
        return prop_kpt11

    def __getPropertyForestDeclaration(self, db):
        values_db = db.GetPropertiesKpt('forest_declaration_style')
        item_value = findProperties(values_db, 'location')

        prop_ForestDeclaration = {}
        prop_ForestDeclaration['locations'] = {}
        prop_ForestDeclaration['locations']['enable'] = True
        prop_ForestDeclaration['locations']['style'] = "Pen (2, 2, 8388608) Brush (63, 0)"
        if item_value is not None:
            prop_ForestDeclaration['locations']['enable'] = item_value['enable']
            prop_ForestDeclaration['locations']['style'] = item_value['style']
        prop_ForestDeclaration['points'] = {}
        prop_ForestDeclaration['points']['enable'] = True
        prop_ForestDeclaration['points']['style'] = "Symbol (49, 65280, 12)"
        item_value = findProperties(values_db, 'points')
        if item_value is not None:
            prop_ForestDeclaration['points']['enable'] = item_value['enable']
            prop_ForestDeclaration['points']['style'] = item_value['style']
        return prop_ForestDeclaration

    def __getPropertyUnder_construction(self,db):
        values_db = db.GetPropertiesKpt('under_construction')
        item_value = findProperties(values_db, 'объекты(контура,линии)')
        prop_Under_construction = {}
        prop_Under_construction['contours'] = {}
        prop_Under_construction['contours']['enable'] = True
        prop_Under_construction['contours']['style'] = "Pen (2, 2, 8388608) Brush (63, 0)"
        if item_value is not None:
            prop_Under_construction['contours']['enable'] = item_value['enable']
            prop_Under_construction['contours']['style'] = item_value['style']
        prop_Under_construction['contours_points'] = {}
        prop_Under_construction['contours_points']['enable'] = True
        prop_Under_construction['contours_points']['style'] = "Symbol (49, 65280, 12)"
        item_value = findProperties(values_db, 'точки')
        if item_value is not None:
            prop_Under_construction['contours_points']['enable'] = item_value['enable']
            prop_Under_construction['contours_points']['style'] = item_value['style']
        return prop_Under_construction

    def __getPropertyEgrn(self,db):
        values_db = db.GetPropertiesKpt('egrn_style')
        item_value = findProperties(values_db, 'contours')

        prop_egrn = {}
        prop_egrn['contours'] = {}
        prop_egrn['contours']['enable'] = True
        prop_egrn['contours']['style'] = "Pen (2, 2, 8388608) Brush (63, 0)"
        if item_value is not None:
            prop_egrn['contours']['enable'] = item_value['enable']
            prop_egrn['contours']['style'] = item_value['style']
        prop_egrn['contours_points'] = {}
        prop_egrn['contours_points']['enable'] = True
        prop_egrn['contours_points']['style'] = "Symbol (49, 65280, 12)"
        item_value = findProperties(values_db, 'contours_points')
        if item_value is not None:
            prop_egrn['contours_points']['enable'] = item_value['enable']
            prop_egrn['contours_points']['style'] = item_value['style']
        values_db = db.GetPropertiesKpt('egrn_style')
        item_value = findProperties(values_db, 'contour_part')
        prop_egrn['parts'] = {}
        prop_egrn['parts']['enable'] = True
        prop_egrn['parts']['style'] = "Symbol (49, 65280, 12)"
        if item_value is not None:
            prop_egrn['parts']['enable'] = item_value['enable']
            prop_egrn['parts']['style'] = item_value['style']
        item_value = findProperties(values_db, 'part_points')
        prop_egrn['points_parts'] = {}
        prop_egrn['points_parts']['enable'] = True
        prop_egrn['points_parts']['style'] = "Symbol (49, 65280, 12)"
        if item_value is not None:
            prop_egrn['points_parts']['enable'] = item_value['enable']
            prop_egrn['points_parts']['style'] = item_value['style']
        return prop_egrn
    def __getPropertyForImportNew(self):
        properties = {}
        db = KptСatalog()
        properties['forestDeclaration']=self.__getPropertyForestDeclaration(db)
        properties['kpt10'] = self.__getPropertyKpt10(db)
        properties['kpt11'] = self.__getPropertyKpt11(db)
        properties['egrn'] = self.__getPropertyEgrn(db)
        properties['under_construction']=self.__getPropertyUnder_construction(db)
        db.close()
        return properties
    def __run(self):
        self.ui.pb_run.setEnabled(False)
        self.ui.pb_cancel.setEnabled(True)
        path_out=self.ui.ln_path_out_file.text()
        cs_mi_out=self.__cs_prj
        #cs_wkt='LOCAL_CS["NonEarth_Meter",UNIT["METER",1]]'
        cs_wkt=self.__cs_axi.wkt
        property_import=self.__getPropertyForImportNew()
        property_import['cs'] = cs_wkt
        property_import['cs_mi'] = self.__cs_axi.prj
        property_import['reverseXY'] = self.ui.ch_reverseXY.isChecked()
        params_for_import={}
        params_for_import['source']=self.__list_source_files
        params_for_import['out']=self.ui.ln_path_out_file.text()
        params_for_import['properties_import']=property_import
        if self.__process is None:
            self.__process = ImportKpT(self)

        else:
            try:
                self.__process.disconnect(self.__update_progress)
            except:
                pass
        self.__process.setParametrs(params_for_import)
        self.__process.updateProcess.connect(self.__update_progress)
        #self.__process.finished.connect(self.__end_process)
        self.__process.updateFormatProgressBar.connect(self.__setFormatprogressBar)
        self.__process.finished.connect(self.__end_process)
        self.thread = QThread()
        self.__process.moveToThread(self.thread)
        self.__process.run()
        #self.thread.start()
    def __run_test(self):
        if self.__process is None:
            self.__process = ImportKpT(self)

        else:
            try:
                self.__process.disconnect(self.__update_progress)
            except:
                pass
        self.__process.updateProcess.connect(self.__update_progress)
        #self.__process.finished.connect(self.__end_process)
        self.__process.updateFormatProgressBar.connect(self.__setFormatprogressBar)
        self.__process.finished.connect(self.__end_process)
        self.__process.run()
    def __update_progress(self,value_main,value_local):
        if value_main>=0:
            self.ui.prog_bar_com.setValue(value_main)
        self.ui.prog_bar_loc.setValue(value_local)
            # print(value)
        time.sleep(0.0001)
        QApplication.processEvents()

    def __end_process(self, value):
        self.ui.pb_run.setEnabled(True)
        self.ui.pb_cancel.setEnabled(False)
        self.__process.updateProcess.disconnect()
        self.__process.finished.disconnect()
        #self.__process.disconnect(self.__end_process)

        self.__process=None
        self.thread=None
        print("end")
    def __setFormatprogressBar(self, str_format_main,str_format_local):
        if str_format_main is not None and len(str_format_main)>0:
            #self.ui.prog_bar_com.setFormat(str_format_main)
            self.ui.label_file.setText(str_format_main)
        if str_format_local is not None:
            self.ui.prog_bar_loc.setFormat(str_format_local)
        import time
        time.sleep(0.0001)
        QApplication.processEvents()

    def __initPropertiesKpt(self,id):
        pass
    @property
    def widget(self):
        return self.ui


    def show(self):
        # self.ui.showMaximized()
        # print("Show Form")
        self.ui.show()
