from os import listdir
from os.path import join, dirname, exists, basename, isdir, isfile

from enmapbox.gui.enmapboxgui import EnMAPBox
from enmapbox.gui.mimedata import MDF_URILIST
from enmapbox.typeguard import typechecked
from enmapboxprocessing.algorithm.importdesisl1balgorithm import ImportDesisL1BAlgorithm
from enmapboxprocessing.algorithm.importdesisl1calgorithm import ImportDesisL1CAlgorithm
from enmapboxprocessing.algorithm.importdesisl2aalgorithm import ImportDesisL2AAlgorithm
from enmapboxprocessing.algorithm.importemitl2aalgorithm import ImportEmitL2AAlgorithm
from enmapboxprocessing.algorithm.importenmapl1balgorithm import ImportEnmapL1BAlgorithm
from enmapboxprocessing.algorithm.importenmapl1calgorithm import ImportEnmapL1CAlgorithm
from enmapboxprocessing.algorithm.importenmapl2aalgorithm import ImportEnmapL2AAlgorithm
from enmapboxprocessing.algorithm.importlandsatl2algorithm import ImportLandsatL2Algorithm
from enmapboxprocessing.algorithm.importplanetscopealgorithm import ImportPlanetScopeAlgorithm
from enmapboxprocessing.algorithm.importprismal1algorithm import ImportPrismaL1Algorithm
from enmapboxprocessing.algorithm.importprismal2balgorithm import ImportPrismaL2BAlgorithm
from enmapboxprocessing.algorithm.importprismal2calgorithm import ImportPrismaL2CAlgorithm
from enmapboxprocessing.algorithm.importprismal2dalgorithm import ImportPrismaL2DAlgorithm
from enmapboxprocessing.algorithm.importproductsdraganddropsupport import AlgorithmDialogWrapper
from enmapboxprocessing.algorithm.importsentinel2l2aalgorithm import ImportSentinel2L2AAlgorithm
from qgis.PyQt import uic
from qgis.PyQt.QtCore import QEvent
from qgis.PyQt.QtWidgets import QDockWidget, QLabel
from qgis.core import QgsRasterLayer, QgsProject
from qgis.gui import QgisInterface


@typechecked
class SensorProductImportDockWidget(QDockWidget):
    mDropArea: QLabel

    EnmapBoxInterface, QgisInterface = 0, 1

    def __init__(self, parent=None):
        # QgsDockWidget.__init__(self, parent)
        super().__init__(parent)
        uic.loadUi(__file__.replace('.py', '.ui'), self)

        # set from outside
        self.interface = None
        self.interfaceType = None

        self.mDropArea.installEventFilter(self)

    def eventFilter(self, source, event):
        if (event.type() == QEvent.DragEnter):
            event.accept()
            return True

        if (event.type() == QEvent.Drop):
            mimeData = event.mimeData()

            if MDF_URILIST in mimeData.formats():
                for url in mimeData.urls():
                    self.openProduct(url.path())
                    break  # diguest only one file
            return True
        return False

    def enmapBoxInterface(self) -> EnMAPBox:
        return self.interface

    def qgisInterface(self):
        return self.interface

    def setInterface(self, interface):
        self.interface = interface
        if isinstance(interface, EnMAPBox):
            self.interfaceType = 0
        elif isinstance(interface, QgisInterface):
            self.interfaceType = 1
        else:
            raise ValueError()

    def openProduct(self, url: str):

        algs = [
            ImportDesisL1BAlgorithm(),
            ImportDesisL1CAlgorithm(),
            ImportDesisL2AAlgorithm(),
            ImportEmitL2AAlgorithm(),
            ImportEnmapL1BAlgorithm(),
            ImportEnmapL1CAlgorithm(),
            ImportEnmapL2AAlgorithm(),
            ImportLandsatL2Algorithm(),
            ImportPlanetScopeAlgorithm(),
            ImportPrismaL1Algorithm(),
            ImportPrismaL2BAlgorithm(),
            ImportPrismaL2CAlgorithm(),
            ImportPrismaL2DAlgorithm(),
            ImportSentinel2L2AAlgorithm()
        ]
        layers = list()
        filename = None
        # check URL
        for alg in algs:
            if isfile(url):
                if alg.isValidFile(url):
                    filename = url
                    break
            elif isdir(url):
                for name in listdir(url):
                    url2 = join(url, name)
                    if alg.isValidFile(url2):
                        filename = url2
                        break
                if filename is not None:
                    break

        # check URL directory
        if filename is None:
            for alg in algs:
                for name in listdir(dirname(url)):
                    url2 = join(dirname(url), name)
                    if alg.isValidFile(url2):
                        filename = url2
                        break
                if filename is not None:
                    break

        if filename is None:
            return

        parameters = alg.defaultParameters(filename)
        alreadyExists = True
        for key, value in parameters.items():
            if key.startswith('output'):
                alreadyExists &= exists(value)
        if not alreadyExists:
            dialog: AlgorithmDialogWrapper = EnMAPBox.showProcessingAlgorithmDialog(
                alg, parameters, True, True, AlgorithmDialogWrapper, False
            )
            if not dialog.finishedSuccessful:
                return
            result = {}  # results will be opened by the processing framework

        else:
            result = {key: value for key, value in parameters.items()
                      if key.startswith('output')}

        for key, value in result.items():
            if parameters[key] is None or value is None:
                continue
            layer = QgsRasterLayer(parameters[key], basename(value))
            layers.append(layer)

        if self.interfaceType == self.EnmapBoxInterface:
            self.enmapBoxInterface().addMapLayers(layers)
        elif self.interfaceType == self.QgisInterface:
            QgsProject.instance().addMapLayers(layers)
