# -*- coding: utf-8 -*-
"""
/***************************************************************************
 ParcelleToActe
								 A QGIS plugin
 Permet d'associer des parcelles à des actes
							  -------------------
		begin				: 2015-06-19
		git sha			  : $Format:%H$
		copyright			: (C) 2015 by CEN Savoie
		email				: a.lesconnec@cen-savoie.org
 ***************************************************************************/

/***************************************************************************
 *																		 *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or	 *
 *   (at your option) any later version.								   *
 *																		 *
 ***************************************************************************/
"""
from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QAction, QTableWidgetItem, QMessageBox

# Initialize Qt resources from file resources.py
from pluginsCenSavoie_v3 import resources

# Import the code for the dialog
from pluginsCenSavoie_v3.tools.parcelle_to_acte_dialog import ParcelleToActeDialog

# Import du fichier de configuration
from pluginsCenSavoie_v3.tools.confPython import bd_cen_host, bd_cen_port, bd_cen_name, bd_cen_mdp_1st_cnx

import os.path
import sys 
import qgis
import os
import psycopg2 
import psycopg2.extras
import base64
import re
from time import localtime, strftime

class ParcelleToActe:
	"""QGIS Plugin Implementation."""

	def __init__(self, iface, cenToolbar):
		"""Constructor.

		:param iface: An interface instance that will be passed to this class
			which provides the hook by which you can manipulate the QGIS
			application at run time.
		:type iface: QgsInterface
		"""
		# Variable HOTE de l'accès à la base de données
		global host
		host = bd_cen_host
		global port
		port = bd_cen_port
		global bdd
		bdd = bd_cen_name		
		global mdp_1st_cnx
		mdp_1st_cnx = bd_cen_mdp_1st_cnx
		global os_user
		if sys.platform == 'linux':
			os_user = os.environ['USER']
		else:
			os_user = os.environ['USERNAME']
			
		# Save reference to the QGIS interface
		self.iface = iface
		self.canvas = self.iface.mapCanvas()
		
		# initialize plugin directory
		self.plugin_dir = os.path.dirname(__file__)
		
		# Create the dialog (after translation) and keep reference
		self.dlg = ParcelleToActeDialog()

		# Add toolbar button
		self.action= QAction(QIcon(":/plugins/pluginsCenSavoie_v3/icons/parcelleToActe.png"),  QCoreApplication.translate('ParcelleToActe', u'Associer des parcelles à un acte'),  self.iface.mainWindow())
		self.action.triggered.connect(self.run)
		self.action.setEnabled(False)
		cenToolbar.addAction(self.action)
		self.canvas.selectionChanged.connect(self.toggle)		
		self.iface.layerTreeView().currentLayerChanged.connect(self.toggle)

	def toggle(self):
		layer = self.iface.activeLayer()
		if layer and layer.type() == layer.VectorLayer:
			if layer.selectedFeatureCount() > 0:
				provider = layer.dataProvider()
				source_postgis = provider.dataSourceUri()
				source_postgis = source_postgis.replace('"', '')				
				if (source_postgis.count('table=foncier.parcelles_dispo ') == 1):
					self.action.setEnabled(True)
				else:
					self.action.setEnabled(False)
			else:
				self.action.setEnabled(False)
		else:
			self.action.setEnabled(False)
			
	def changeCellValue(self, ligne, col):
		self.dlg.tbl_detail.blockSignals(True)
		if self.dlg.tbl_detail.item(ligne, 2).text() == 'OUI' and col != 0:
			self.dlg.tbl_detail.setItem(ligne, 2, QTableWidgetItem('NON'))
			self.dlg.tbl_detail.item(ligne, 1).setBackground(QtGui.QColor(255, 145, 145))
			self.dlg.tbl_detail.item(ligne, 2).setBackground(QtGui.QColor(255, 145, 145))
		elif self.dlg.tbl_detail.item(ligne, 2).text() == 'NON' and col != 0:
			self.dlg.tbl_detail.setItem(ligne, 2, QTableWidgetItem('OUI'))
			self.dlg.tbl_detail.item(ligne, 1).setBackground(QtGui.QColor(115, 215, 115))
			self.dlg.tbl_detail.item(ligne, 2).setBackground(QtGui.QColor(115, 215, 115))
		self.dlg.tbl_detail.item(ligne, col).setSelected(False)	
		self.dlg.tbl_detail.blockSignals(False)
		
	def chg_date_modif(self):		
		self.dlg.cal_date_modif.setEnabled(True)
		self.dlg.cal_date_modif.setVisible(1)

	def chg_cal_date_modif(self, date):
		current_date_modif = date.toString('yyyy-MM-dd')
		self.dlg.date_modif.setText(str(current_date_modif))
		self.dlg.cal_date_modif.setEnabled(False)
		self.dlg.cal_date_modif.setVisible(0)
		if self.dlg.lst_actes.currentIndex() != -1 and self.dlg.date_modif.text() != 'N.P.' and self.dlg.lst_motif_maj.currentIndex() != -1 :
			self.dlg.button_box.setEnabled(True)
		else:
			self.dlg.button_box.setEnabled(False)
		
	def run(self):
		"""Run method that performs all the real work"""
		# initialise le contenant du formulaire
		self.dlg.tbl_detail.setColumnCount(4)
		self.dlg.tbl_detail.setHorizontalHeaderItem(0, QTableWidgetItem('Par ID'))
		self.dlg.tbl_detail.setHorizontalHeaderItem(1, QTableWidgetItem('Lot ID'))
		self.dlg.tbl_detail.setHorizontalHeaderItem(2, QTableWidgetItem('A Associer'))
		self.dlg.tbl_detail.setHorizontalHeaderItem(3, QTableWidgetItem('cad_site_id'))
		self.dlg.tbl_detail.setColumnHidden(3, True)
		self.dlg.btn_date_modif.clicked.connect(self.chg_date_modif)
		self.dlg.cal_date_modif.clicked.connect(self.chg_cal_date_modif)		
		self.dlg.tbl_detail.cellClicked.connect(self.changeCellValue)
		
		first_conn = psycopg2.connect("host=" + host + " port=" + port + " dbname=" + bdd + " user=first_cnx password=" + mdp_1st_cnx)
		first_cur = first_conn.cursor(cursor_factory = psycopg2.extras.DictCursor)
		first_cur.execute("SELECT mdp_cen, usename FROM pg_catalog.pg_user t1, admin_sig.utilisateurs t2 WHERE t2.oid = t1.usesysid AND (utilisateur_id = '" + os_user + "' OR utilisateur_os = '" + os_user + "')")
		res_ident = first_cur.fetchone()
		mdp = base64.b64decode(str(res_ident[0])).decode('utf-8')
		user = res_ident[1]
		conn = psycopg2.connect("host=" + host + " port=" + port + " dbname=" + bdd + " user=" + user + " password=" + mdp)
		cur = conn.cursor(cursor_factory = psycopg2.extras.DictCursor)
		first_conn.close()
			
		site_id = []
		tbl_dnulot = []
		tbl_cad_site_id = []
		self.canvas = self.iface.mapCanvas()
		global layer
		layer = self.iface.activeLayer()
		rowCount = 0
		for feature in layer.selectedFeatures():
			site_id.append(feature["site_id"])
			tbl_dnulot = re.split(',', feature["tbl_dnulot"])
			if len(tbl_dnulot) > 0:
				j = 0
				while j < len(tbl_dnulot):
					rowCount += 1
					j+=1
		self.dlg.tbl_detail.setRowCount(rowCount)
		
		for id_site in site_id:
			rq_lst_sites_around = """
			SELECT site_id 
			FROM sites.sites 
			WHERE st_distance(geom_ecolo, (SELECT geom_ecolo FROM sites.sites WHERE site_id = '"""+id_site+"""')) < 1000 AND site_id != '"""+id_site+"""'
			"""			
			with conn:
				with conn.cursor() as cur:
					cur.execute(rq_lst_sites_around)
					res_lst_sites_around = cur.fetchall()
					site_id_around = []
					if len(res_lst_sites_around) > 0:
						i = 0
						while i < len(res_lst_sites_around):
							if res_lst_sites_around[i][0] not in site_id and res_lst_sites_around[i][0] not in site_id_around:
								site_id_around.append(res_lst_sites_around[i][0])
							i=i+1
					site_id = [*site_id, *site_id_around]
		
		if rowCount > 0:
			ligne = 0
			col = 0
			for feature in layer.selectedFeatures():
				tbl_dnulot = re.split(',', feature["tbl_dnulot"])
				tbl_cad_site_id = re.split(',', feature["tbl_cad_site_id"])
				if len(tbl_dnulot) > 0:
					self.dlg.tbl_detail.setItem(ligne, 0, QTableWidgetItem(feature["par_id"]))
					self.dlg.tbl_detail.setSpan(ligne, 0, len(tbl_dnulot), 1)
					j = 0
					while j < len(tbl_dnulot):
						self.dlg.tbl_detail.setItem(ligne, 1, QTableWidgetItem(tbl_dnulot[j]))
						self.dlg.tbl_detail.item(ligne, 1).setBackground(QtGui.QColor(115, 215, 115))
						self.dlg.tbl_detail.setItem(ligne, 2, QTableWidgetItem('OUI'))
						self.dlg.tbl_detail.item(ligne, 2).setBackground(QtGui.QColor(115, 215, 115))
						self.dlg.tbl_detail.setItem(ligne, 3, QTableWidgetItem(tbl_cad_site_id[j]))
						ligne += 1
						j+=1
			self.dlg.tbl_detail.setEnabled(True)
			self.dlg.no_lot.setVisible(0)
		else:
			self.dlg.tbl_detail.setEnabled(False)
			self.dlg.no_lot.setVisible(1)
		
		self.dlg.tbl_detail.resizeColumnsToContents()
				
		if (len(set(site_id)) < 1):
			QMessageBox.warning(None, "Oups:", 'Selection invalide')			
		else:	
			tbl_site_id = list(set(site_id))
			self.dlg.InitFormulaire(tbl_site_id, 'load', user, mdp)
			self.dlg.img_logo.setPixmap(QPixmap(":/plugins/pluginsCenSavoie_v3/tools/images/Logo_CEN_Savoie.png"))
			self.dlg.lbl_fond.setPixmap(QPixmap("%s/images/fond_70.png"%self.plugin_dir))
			self.dlg.lbl_fond.stackUnder(self.dlg.button_box)
			# show the dialog
			self.dlg.show()
				
			# Run the dialog event loop
			result = self.dlg.exec_()
			# See if OK was pressed
			if result:
				curs = QCursor()
				curs.setShape(Qt.WaitCursor)
				qgis.utils.iface.mainWindow().centralWidget().setCursor(curs)
				
				mfu_id = self.dlg.lst_actes.currentText()
				motif_maj_id = self.dlg.motif_maj_id.text()
				mfu_table = self.dlg.type_acte_sel.text()
				aujourdhui = strftime("%Y-%m-%d %H:%M:%S", localtime())
				date_modif = self.dlg.date_modif.text()
				maj_table = 'NON'
				
				with conn:
					with conn.cursor() as cur:		
						rq_check_droit = """
						WITH RECURSIVE t(oid) AS (
							VALUES ((SELECT oid FROM admin_sig.utilisateurs WHERE utilisateur_id = '""" + os_user + """' OR utilisateur_os = '""" + os_user + """'))
							UNION ALL
							SELECT grosysid
							FROM pg_catalog.pg_group JOIN t ON (t.oid = ANY (grolist))
						),
						t_group AS (
							SELECT DISTINCT groname
							FROM pg_catalog.pg_group JOIN t ON (t.oid = pg_group.grosysid))

						SELECT 
							count(*) FILTER (WHERE grant_elt_id = 3 AND grant_group_droit = 't' AND grant_group_id IN (groname)) as parc
						FROM foncier.grant_group JOIN t_group ON (groname = grant_group_id)"""
						cur.execute(rq_check_droit)
						can_parc_site = cur.fetchone()
						if can_parc_site[0] == 0:
							QMessageBox.warning(None, "ERROR:", """Le traitement a échoué<br>Vous n'êtes pas autorisé à modifier la liste des parcelles d'un acte""")
						else:
							rq_statut_mfu = "SELECT statutmfu_id AS statut_id FROM alertes.v_tdb_mfu WHERE mfu_id = '"+mfu_id+"'"
							cur.execute(rq_statut_mfu)
							statut_mfu = cur.fetchone()
							if (int(statut_mfu[0]) == 0):
								date_modif = '0000-00-00'
							else:
								date_modif = date_modif + ' 00:00:00'
								
							if mfu_table == 'r_cad_site_mf':
								rq_date_debut_acte = "SELECT date_sign_acte FROM foncier.mf_acquisitions WHERE mf_id = '"+mfu_id+"'"
								suffixe = 'mf'
							else:
								rq_date_debut_acte = "SELECT date_effet_conv FROM foncier.mu_conventions WHERE mu_id = '"+mfu_id+"'"
								suffixe = 'mu'								
							
							error_date = 'RAS'
							tbl_cad_site_id = []
							for i in range(self.dlg.tbl_detail.rowCount()):
								tbl_cad_site_id.append(self.dlg.tbl_detail.item(i, 3).text()) 
							lst_cad_site_id = ','.join(tbl_cad_site_id)	
							
							rq_check_mfu = """
							WITH t1 AS (
								SELECT cad_site_id
								FROM
									alertes.v_tdb_mfu
									JOIN foncier.r_cad_site_mu ON (mu_id = mfu_id)
								WHERE statutmfu_id = 1
								UNION
								SELECT cad_site_id
								FROM
									alertes.v_tdb_mfu
									JOIN foncier.r_cad_site_mf ON (mf_id = mfu_id)
								WHERE statutmfu_id = 1
							)
							SELECT cad_site_id FROM t1 WHERE cad_site_id IN (""" + str(lst_cad_site_id) + """)"""
							cur.execute(rq_check_mfu)
							res_check_mfu = cur.fetchall()
							if len(res_check_mfu) > 0 and int(statut_mfu[0]) == 1:
								error_date = 'PROB'
								QMessageBox.warning(None, "ERROR:", """Le traitement a échoué<br>Au moins une parcelle est déjà maitrisée""")							
							elif int(motif_maj_id) in [3, 10]:
								rq_check_date = """
								SELECT
									cad_site_id
								FROM
									foncier.cadastre_site
									JOIN cadastre.cadastre_cen USING (cad_cen_id)
								WHERE
									cad_site_id IN (""" + str(lst_cad_site_id) + """) AND
									'"""+date_modif+"""'::character varying(10) < ("""+rq_date_debut_acte+""")::character varying(10)"""
								cur.execute(rq_check_date)
								res_check_date = cur.fetchall()
								if len(res_check_date) > 0:
									error_date = 'PROB'
									QMessageBox.warning(None, "ERROR:", """Le traitement a échoué<br>Au moins une parcelle ajoutée avant la création de l'acte""")
							elif int(motif_maj_id) == 9:
								rq_check_date = """
								SELECT
									cad_site_id
								FROM
									foncier.cadastre_site
									JOIN cadastre.cadastre_cen USING (cad_cen_id)
								WHERE
									cad_site_id IN ("""+str(lst_cad_site_id)+""") AND
									cadastre_cen.date_deb::character varying(10) < ("""+rq_date_debut_acte+""")::character varying(10)"""
								cur.execute(rq_check_date)
								res_check_date = cur.fetchall()
								if len(res_check_date) > 0:
									error_date = 'PROB'
									QMessageBox.warning(None, "ERROR:", """Le traitement a échoué<br>Au moins une parcelle ajoutée avant la création de l'acte""")
							
							if error_date == 'RAS':	
								rq_ajout = "INSERT INTO foncier.r_cad_site_"+suffixe+" (cad_site_id, "+suffixe+"_id, date_entree, date_sortie, motif_entree_id, motif_sortie_id) VALUES ";
								for i in range(self.dlg.tbl_detail.rowCount()):
									if self.dlg.tbl_detail.item(i, 2).text() == 'OUI':								
										if int(motif_maj_id) == 1 and int(statut_mfu[0]) != 0:
											rq_ajout += "("+self.dlg.tbl_detail.item(i, 3).text()+", '"+mfu_id+"', ("+rq_date_debut_acte+"), 'N.D.', "+motif_maj_id+", 1), "
										elif int(motif_maj_id) == 9:
											rq_ajout += "("+self.dlg.tbl_detail.item(i, 3).text()+", '"+mfu_id+"', (SELECT cadastre_cen.date_deb FROM cadastre.cadastre_cen JOIN foncier.cadastre_site USING (cad_cen_id) WHERE cad_site_id = "+self.dlg.tbl_detail.item(i, 3).text()+"), 'N.D.', "+motif_maj_id+", 1), "
										else:
											rq_ajout += "("+self.dlg.tbl_detail.item(i, 3).text()+", '"+mfu_id+"', '"+date_modif+"', 'N.D.', "+motif_maj_id+", 1), "
								if rq_ajout[-2:] == ', ':
									rq_ajout = rq_ajout[0:-2]
								if self.dlg.tbl_detail.rowCount() > 0 and rq_ajout != "INSERT INTO foncier.r_cad_site_"+suffixe+" (cad_site_id, "+suffixe+"_id, date_entree, date_sortie, motif_entree_id, motif_sortie_id) VALUES ":
									cur.execute(rq_ajout)
									conn.commit()
									maj_table = 'OUI'
								
								if maj_table == 'OUI':
									rq_refresh = """
									WITH t1 AS (
										SELECT array_to_string(array_agg(DISTINCT site_id), ',') as lst_site_id 
										FROM 
											foncier."""+mfu_table+"""
											JOIN foncier.cadastre_site USING (cad_site_id)
										WHERE """+mfu_table[len(mfu_table)-2:len(mfu_table)]+"""_id = '"""+mfu_id+"""' 
									)
									SELECT admin_sig.refresh_mview_foncier(t1.lst_site_id) FROM t1"""
									cur.execute(rq_refresh)
									conn.commit()
									
									if mfu_table == 'r_cad_site_mu':
										rq_update = "UPDATE foncier.mu_conventions SET maj_date = '"+aujourdhui+"', maj_user = '"+os_user+"' WHERE mu_id = '"+mfu_id+"'"
									elif mfu_table == 'r_cad_site_mf':
										rq_update = "UPDATE foncier.mf_acquisitions SET maj_date = '"+aujourdhui+"', maj_user = '"+os_user+"' WHERE mf_id = '"+mfu_id+"'"
													
									cur.execute(rq_update)
									conn.commit()
				curs = QCursor()
				curs.setShape(Qt.ArrowCursor)
				qgis.utils.iface.mainWindow().centralWidget().setCursor(curs)
				self.canvas.refresh()