from qgis.PyQt.QtCore import (
  QT_TRANSLATE_NOOP, QVariant
  )
from qgis.core import (
  QgsProcessing,
  QgsProcessingParameterFeatureSource,
  QgsProcessingParameterFeatureSink,
  QgsProcessingParameterBoolean,
  QgsFeatureRequest,
  QgsVectorLayer,
  QgsProcessingParameterCrs
  )

from .initabstract import initabstract
from qgis import processing
import sys

class initbuilding(initabstract):
  PARAMETERS = {                  
    "INPUT": {
      "ui_func": QgsProcessingParameterFeatureSource,
      "ui_args":{
        "description": QT_TRANSLATE_NOOP("initbuilding","Polygon layer"),
        "types": [QgsProcessing.TypeVectorPolygon],
        "optional": True
      }
    },
    "TARGET_CRS": {
      "ui_func": QgsProcessingParameterCrs,
      "ui_args": {
        "description": QT_TRANSLATE_NOOP("initbuilding","Target CRS (Cartesian coordinates)")
      }
    },
    "OVERWRITE": {
      "ui_func": QgsProcessingParameterBoolean,
      "ui_args":{
        "description" : QT_TRANSLATE_NOOP("initbuilding","Overwrite existing fields?"),
        "defaultValue": True
      }
    },
    "OUTPUT": {
      "ui_func": QgsProcessingParameterFeatureSink,
      "ui_args": {
        "description": QT_TRANSLATE_NOOP("initbuilding","Building" )
      }
    }
  }
  
  def __init__(self):
    super().__init__()
    self.FIELDS_REQUIRED.update(
      {
        "height":  {"TYPE": QVariant.Double, "DEFAULT_VALUE": 6.0},
        "pop":     {"TYPE": QVariant.Double, "DEFAULT_VALUE": None}
      }
    )
      
  def initAlgorithm(self, config):
    (rect, target_crs) = self.getExtentAndCrsUsingCanvas()
    self.PARAMETERS["TARGET_CRS"]["ui_args"]["defaultValue"] = target_crs.authid()

    self.initParameters()
    
  def processAlgorithm(self, parameters, context, feedback):   
    
    target_crs = self.parameterAsCrs(parameters, "TARGET_CRS", context)
    # check whether the target CRS is x-y coordinates
    if target_crs.isGeographic() or target_crs.authid() == "EPSG:3857":
      sys.exit(self.tr("The Target CRS is NOT a Cartesian Coordinate System"))

    try:
      self.INPUT_LAYER = processing.run(
        "native:reprojectlayer", 
        {
          "INPUT": self.parameterAsSource(parameters, "INPUT", context).materialize(QgsFeatureRequest(), feedback),
          "TARGET_CRS": target_crs,
          "OUTPUT": "TEMPORARY_OUTPUT"
        }
      )["OUTPUT"]      
            
    except:
      self.INPUT_LAYER = QgsVectorLayer(f"Polygon?crs={target_crs.authid()}", "temp", "memory")
    
     
    self.setFieldsDict(
      parameters, context, feedback, 
      self.INPUT_LAYER.fields(), 
      self.parameterAsBoolean(parameters, "OVERWRITE", context)
    )
    
    
    # define the feature sink
    (sink, dest_id) = self.parameterAsSink(
      parameters, "OUTPUT", context, 
      self.FIELDS_INIT, 
      self.INPUT_LAYER.wkbType(), 
      self.INPUT_LAYER.sourceCrs()
    )
    
    self.resetPk()
    self.addFeaturesToSink(sink, dest_id, self.INPUT_LAYER)
              
    return {"OUTPUT": dest_id}
  
  def createInstance(self):
    return initbuilding()

  def displayName(self):
    return self.tr("Building")

  def group(self):
    return self.tr("Initialize features")

  def groupId(self):
    return "initfeature"

  def createInstance(self):
    return initbuilding()
