# -*- coding: utf-8 -*-
import os
import sys
import json
import log
import appconfig
import arcpy
import utils
from arcpy import env
from db.postgresql import Postgresql

import importlib, sys

importlib.reload(sys)


class Xmydsyx:
    def __init__(self, data):
        self.bsm = data
        self.db = Postgresql(appconfig.DB_CONN)
        self.outputname = "XMYDSYX" + data
        log.info(data)
        # 根据BSM获取任务信息
        self.task()
        # 临时工作空间
        self.root = os.path.dirname(os.path.abspath(__file__))
        path = os.path.join(self.root, "out")
        if not os.path.exists(path):
            os.makedirs(path)
        # 创建输出GDB，如果已存在则删除后新建
        self.outGdb = os.path.join(path, "{0}.gdb".format(data))
        arcpy.Delete_management(self.outGdb)
        arcpy.CreateFileGDB_management(path, "{0}.gdb".format(data))
        # 输出文件夹里面已经有内容的，就覆盖掉
        env.overwriteOutput = True
        # 设置工作空间
        env.workspace = appconfig.SDE["KJGH"]

    def task(self):
        # 根据BSM获取任务信息
        sql = f'select t.id "ID",m.fxtable "FXTABLE",y.name "NAME",y.sjlx "SJLX" from onemap.t_fxpj_xmyd_rz t left join onemap.t_fxpj_ctfx_main m on m.id = t.rwbsm ' \
              f'left join onemap.t_fxpj_ctfx_yz y on y.id = t.yzbsm where t.rwbsm = \'{self.bsm}\''
        tasks = self.db.query(sql)
        if len(tasks) == 0:
            raise Exception("任务标识错误[{0}]".format(self.bsm))
        self.tasks = tasks

    def run(self):
        try:
            self.fxjgtable = "result_" + self.bsm
            # 记录任务开始时间
            self.rwkssj = utils.getNowTimeStr("%Y-%m-%d %H:%M:%S")
            mjField = "TBMJ"
            syxField = "SYX"
            markField = "SW_XZQH"
            # 配置以哪个适宜性为主
            firstStyle = "0"
            fxtable = ""
            # 记录主任务开始时间并写入表
            # 遍历分析因子 进行叠加分析
            for curtask in self.tasks:
                curkssj = utils.getNowTimeStr("%Y-%m-%d %H:%M:%S")
                try:
                    fxtable = curtask["FXTABLE"]
                    # 创建当前分析因子叠加结果表
                    curtablename = curtask["SJLX"]
                    curt = r"{0}\{1}".format(self.outGdb, curtablename)
                    # 使用要素识别，用影响因子切分项目范围
                    arcpy.Identity_analysis(fxtable, "SDE." + curtask["SJLX"], curt, "ALL", 0)
                    # 计算面积
                    arcpy.AddField_management(curt, mjField, "DOUBLE")
                    arcpy.CalculateField_management(curt, mjField, "!shape.area@SQUAREMETERS!", "PYTHON_9.3")
                    # 增加适宜性字段
                    arcpy.AddField_management(curt, syxField, "TEXT")
                    # 遍历数据 设置markField不为空则表示压覆，反之则不压覆，并计算各类面积统计
                    syArea = 0  # 适宜面积统计
                    bsyArea = 0  # 不适宜面积统计
                    totalArea = 0
                    with arcpy.da.UpdateCursor(curt, [markField, syxField, mjField]) as cursor:
                        for row in cursor:
                            if row[0] != None and row[0] != "":
                                row[1] = "0"
                                bsyArea = bsyArea + row[2]
                            else:
                                row[1] = "1"
                                syArea = syArea + row[2]
                            totalArea = totalArea + row[2]
                            cursor.updateRow(row)
                    # 组装返回结果
                    self.updateFxyzzt(curtask["ID"], "2", curkssj, curtablename,
                                      self.arrangeFxjg(syArea, bsyArea, totalArea))
                except arcpy.ExecuteError:
                    log.error(arcpy.GetMessages())
                    self.updateFxyzzt(curtask["ID"], "3", curkssj, curtablename, arcpy.GetMessages())
                except:
                    msg = str(sys.exc_info()).decode('string-escape')
                    log.error(msg)
                    self.updateFxyzzt(curtask["ID"], "3", curkssj, curtablename, msg)
            # 遍历分析因子 将权重高的数据类型统一提取到临时表
            templist = []
            for curtask in self.tasks:
                curtablename = curtask["SJLX"]
                curt = r"{0}\{1}".format(self.outGdb, curtablename)
                tempt = r"{0}\{1}".format(self.outGdb, "temp" + curtablename)
                templist.append(tempt)
                arcpy.Select_analysis(curt, tempt, "" + syxField + " = '" + firstStyle + "'")
            # 将权重数据提取到一张临时表进行要素图斑范围合并
            merget = "{0}\{1}".format(self.outGdb, "merge_" + firstStyle)
            # 定义合并字段
            # fldmap = arcpy.FieldMap()
            # for cur in templist:
            #     fldmap.addInputField(cur, markField)
            # fldmap_outField = fldmap.outputField
            # fldmap_outField.name = markField
            # fldmap.outputField = fldmap_outField
            # fieldmappings = arcpy.FieldMappings()
            # for cur in templist:
            #     fieldmappings.addTable(cur)
            # fieldmappings.addFieldMap(fldmap)
            arcpy.Merge_management(templist, merget)
            mergelast = r"{0}\{1}".format(self.outGdb, "mergelast_" + firstStyle)
            arcpy.Dissolve_management(merget, mergelast)
            arcpy.AddField_management(mergelast, markField, "TEXT")
            arcpy.CalculateField_management(mergelast, markField, "'1'", "PYTHON_9.3")
            # 使用要素识别，用影响因子切分项目范围
            fxjgtable = r"{0}\{1}".format(self.outGdb, self.fxjgtable)
            arcpy.Identity_analysis(fxtable, mergelast, fxjgtable, "ALL", 0)
            # 计算面积
            arcpy.AddField_management(fxjgtable, mjField, "DOUBLE")
            arcpy.CalculateField_management(fxjgtable, mjField, "!shape.area@SQUAREMETERS!", "PYTHON_9.3")
            # 增加适宜性字段
            arcpy.AddField_management(fxjgtable, syxField, "TEXT")
            # 遍历数据 设置markField不为空则表示压覆，反之则不压覆，并计算各类面积统计
            syArea = 0  # 适宜面积统计
            bsyArea = 0  # 不适宜面积统计
            totalArea = 0
            with arcpy.da.UpdateCursor(fxjgtable, [markField, syxField, mjField]) as cursor:
                for row in cursor:
                    if row[0] != None and row[0] != "":
                        row[1] = "0"
                        bsyArea = bsyArea + row[2]
                    else:
                        row[1] = "1"
                        syArea = syArea + row[2]
                    totalArea = totalArea + row[2]
                    cursor.updateRow(row)
            # 组装返回结果
            self.updateFxzt(self.bsm, "2", self.arrangeFxjg(syArea, bsyArea, totalArea))
            log.info("####OK####")
            print("####OK####")
        except arcpy.ExecuteError:
            print("####ERROR####" + arcpy.GetMessages())
            log.error(arcpy.GetMessages())
            self.updateFxzt(self.bsm, "3", arcpy.GetMessages())
        except:
            msg = str(sys.exc_info()).decode('string-escape')
            print("####ERROR####" + msg)
            log.error(msg)
            self.updateFxzt(self.bsm, "3", msg)

    # 整理统计数据
    def arrangeFxjg(self, syArea, bsyArea, totalArea):
        obj = {
            "sy": {
                "area": "%.2f" % syArea,
                "proportion": "" + "%.2f" % (syArea / totalArea * 100) + "%"
            },
            "bsy": {
                "area": "%.2f" % bsyArea,
                "proportion": "" + "%.2f" % (bsyArea / totalArea * 100) + "%"
            }
        }
        return json.dumps(obj)

    # 更新分析因子任务状态
    def updateFxyzzt(self, bsm, fxzt, rwkssj, outputname, msg):
        # 记录任务结束时间
        rwjssj = utils.getNowTimeStr("%Y-%m-%d %H:%M:%S")
        sql = "update onemap.t_fxpj_xmyd_rz t set rwzt = '{0}',rwkssj = to_date('{1}','yyyy-mm-dd hh24:mi:ss') , rwjssj = to_date('{2}','yyyy-mm-dd hh24:mi:ss') ,statist = '{3}',fxjgtable = '{4}',workspace = '{5}' where t.id = '{6}'"
        sql = sql.format(
            fxzt
            , rwkssj
            , rwjssj
            , msg
            , outputname
            , self.outGdb
            , bsm)
        self.db.insert(sql)

    # 更新冲突分析任务状态
    def updateFxzt(self, bsm, fxzt, msg):
        # 记录任务结束时间
        self.rwjssj = utils.getNowTimeStr("%Y-%m-%d %H:%M:%S")
        sql = "update onemap.t_fxpj_ctfx_main t set rwzt = '{0}',rwkssj = to_date('{1}','yyyy-mm-dd hh24:mi:ss') , rwjssj = to_date('{2}','yyyy-mm-dd hh24:mi:ss') ,fxjg = '{3}',fxjgtable = '{4}',workspace = '{5}' where t.id = '{6}'"
        sql = sql.format(
            fxzt
            , self.rwkssj
            , self.rwjssj
            , msg
            , self.fxjgtable
            , self.outGdb
            , bsm)
        self.db.insert(sql)
