import os

from osgeo import gdal
from qgis import processing
from qgis.analysis import QgsRasterCalculator, QgsRasterCalculatorEntry
from qgis.core import QgsCoordinateReferenceSystem, QgsProject, QgsRasterLayer

from kfrm_tool.include.File_Class import ChFile_Exists, ChFile_N_MkDir, GetFile_Name
from kfrm_tool.include.setting.path_list import DefaultPath


class RasterToVector:
    def __init__(self):
        self.pathList = DefaultPath()
        tempPath = self.pathList.getTempPath()
        ChFile_N_MkDir(tempPath)

    def rasToVec(self, path, type=1, rename="convert", con=""):
        tempPath = self.pathList.getTempPath()
        rePath = f"{tempPath}/{rename}.shp"
        if ChFile_Exists(rePath):
            for ex in [".shp", ".shx", ".dbf"]:
                os.remove(rePath[:-4] + ex)

        if type == 1:
            # 동일 이름의 tif 파일이 있으면 기존 값에 덮어씌워짐..
            if ChFile_Exists(rePath[:-3] + "tif"):
                os.remove(rePath[:-3] + "tif")

            params = {
                "FIELD_NAME": "depth",
                "INPUT_RASTER": path,
                "OUTPUT": rePath,
                "RASTER_BAND": 1,
            }
            processing.run("qgis:pixelstopolygons", params)

        else:
            params = {
                "BAND": 1,
                "EIGHT_CONNECTEDNESS": False,
                "EXTRA": "",
                "FIELD": "depth",
                "INPUT": path,
                "OUTPUT": rePath,
            }
            processing.run("gdal:polygonize", params)

        return rePath

    def standardization(self, path, type=1, rename="convert"):
        calc = ""
        tempPath = self.pathList.getTempPath() + f"/{rename}.tif"
        fileName = GetFile_Name(path)[:-4]

        raster = gdal.Open(path)  # open raster file
        band = raster.GetRasterBand(
            1
        )  # get data into varialbe 'band' so we can actually look at it.
        nodata = -9999
        val = 1 if type == 2 else f'"{fileName}"'

        if type == 1:  # 단계화 0~11
            calc = f'(0 >= "{fileName}") * {nodata} + (0 < "{fileName}" AND "{fileName}" < 0.3) * 1 + '
            for i in range(1, 10):
                calc += f'({i*0.3} <= "{fileName}" AND "{fileName}" < {(i+1)*0.3}) * {i+1} + '
            calc += f'(3.0 <= "{fileName}") * 11'
        else:  # nodata 처리 : 0보다 작은 값들은 전부 nodata로 처리
            calc = f'(0 >= "{fileName}") * {nodata} + (0 < "{fileName}") * {val}'

        rasterLayer = QgsRasterLayer(path, fileName)
        ras = QgsRasterCalculatorEntry()
        ras.ref = fileName
        ras.raster = rasterLayer
        ras.bandNumber = 1  # 다중 밴드 사진일 때 밴드 순서 호출
        entries = [ras]
        result = QgsRasterCalculator(
            calc,
            tempPath,
            "GTiff",
            rasterLayer.extent(),
            rasterLayer.width(),
            rasterLayer.height(),
            entries,
        )

        if result.processCalculation() != 0:
            print("error")

        raster = gdal.Open(tempPath)  # open raster file
        band = raster.GetRasterBand(
            1
        )  # get data into varialbe 'band' so we can actually look at it.
        band.SetNoDataValue(nodata)

        return tempPath

    def getFileLayerSimplify(self, path):
        # 레이어 경계따라 생성된 사각형 모양의 Polygon으로 상하좌우 끝에 위치한 객체 추출 + 레이어 영역내에 랜덤으로 생성된 Polygon(Point를 변환함)
        dic = {
            1: [
                "qgis:polygonfromlayerextent",
                {"INPUT": path, "OUTPUT": "TEMPORARY_OUTPUT", "ROUND_TO": 0},
            ],
            2: ["native:polygonstolines", {"INPUT": "", "OUTPUT": "TEMPORARY_OUTPUT"}],
            3: [
                "native:buffer",
                {
                    "INPUT": "",
                    "DISSOLVE": False,
                    "DISTANCE": 0.1,
                    "END_CAP_STYLE": 1,
                    "JOIN_STYLE": 0,
                    "MITER_LIMIT": 2,
                    "OUTPUT": "TEMPORARY_OUTPUT",
                    "SEGMENTS": 5,
                },
            ],
            4: [
                "native:buffer",
                {
                    "DISSOLVE": False,
                    "DISTANCE": 0.1,
                    "END_CAP_STYLE": 1,
                    "INPUT": path,
                    "JOIN_STYLE": 0,
                    "OUTPUT": "TEMPORARY_OUTPUT",
                },
            ],
            5: [
                "qgis:randompointsinlayerbounds",
                {
                    "INPUT": "",
                    "MIN_DISTANCE": 1500,
                    "OUTPUT": "TEMPORARY_OUTPUT",
                    "POINTS_NUMBER": 10,
                },
            ],
            6: [
                "native:buffer",
                {
                    "DISSOLVE": False,
                    "DISTANCE": 0.1,
                    "END_CAP_STYLE": 2,
                    "INPUT": "",
                    "JOIN_STYLE": 0,
                    "OUTPUT": "TEMPORARY_OUTPUT",
                },
            ],
            7: [
                "native:union",
                {
                    "INPUT": "",
                    "OUTPUT": "TEMPORARY_OUTPUT",
                    "OVERLAY": "",
                    "OVERLAY_FIELDS_PREFIX": "",
                },
            ],
            8: [
                "native:dissolve",
                {"FIELD": [], "INPUT": "", "OUTPUT": "TEMPORARY_OUTPUT"},
            ],
            9: [
                "native:reprojectlayer",
                {
                    "INPUT": "",
                    "OUTPUT": "TEMPORARY_OUTPUT",
                    "TARGET_CRS": QgsCoordinateReferenceSystem("EPSG:5179"),
                },
            ],
        }

        lryList = []
        for i in range(1, 10):
            dic[i][1]["INPUT"] = (
                path if dic[i][1]["INPUT"] != "" else lryList[-1].source()
            )
            if i == 7:
                dic[i][1]["INPUT"] = lryList[2].source()
                dic[i][1]["OVERLAY"] = lryList[-1].source()

            lryList.append(processing.run(dic[i][0], dic[i][1])["OUTPUT"])
            QgsProject.instance().addMapLayer(lryList[-1], False)

        geom = [g for g in lryList[-1].getFeatures()][0].geometry().asWkt()
        QgsProject.instance().removeMapLayers([l.id() for l in lryList])

        return geom
