# Copyright (c) 2026, UChicago Argonne, LLC
# BSD OPEN SOURCE LICENSE. Full license can be found in LICENSE
# Copyright (c) 2026, UChicago Argonne, LLC
# BSD OPEN SOURCE LICENSE. Full license can be found in LICENSE
from os.path import dirname, join

import pandas as pd
from polaris.network.consistency.network_objects.location import Location
from polaris.network.consistency.network_objects.parking import Parking
from polaris.network.tools.geo import Geo
from polaris.utils.database.db_utils import read_and_close, commit_and_close
from qgis.PyQt import uic
from qgis.PyQt.QtWidgets import QDialog
from qgis.core import QgsProject
from qgis.core import QgsVectorLayer

FORM_CLASS, _ = uic.loadUiType(join(dirname(__file__), "forms/zones_no_locations.ui"))


class ZonesWithNoLocations(QDialog, FORM_CLASS):
    def __init__(self, _PQgis):
        QDialog.__init__(self)
        self.iface = _PQgis.iface
        self.setupUi(self)

        self._PQgis = _PQgis
        self._p = _PQgis.network
        self.worker_thread = self._p.tools
        self.was_mapped = False
        self.empty_zones = []

        self.but_map_empty.clicked.connect(self.map_zones)
        self.but_fill_empty.clicked.connect(self.fill_locations)
        self.but_fill_empty.setEnabled(False)
        self.setFixedHeight(140)

        self.zones_layer = self._PQgis.layers["zone"][0]
        style_fldr = join(dirname(dirname(__file__)), "style_loader", "styles")
        self.zones_layer.loadNamedStyle(join(style_fldr, "zone_background.qml"), True)
        QgsProject.instance().addMapLayer(self.zones_layer)

        self.loc_layer = self._PQgis.layers["location"][0]
        QgsProject.instance().addMapLayer(self.loc_layer)
        self.run_consistency_after = True

    def map_zones(self):
        sql = "select z.zone from Zone z where z.zone not in (select distinct(zone) from Location);"
        with read_and_close(self._p.path_to_file, spatial=True) as conn:
            self.empty_zones = [x[0] for x in conn.execute(sql).fetchall()]
        if not self.empty_zones:
            return

        qry = f"={self.empty_zones[0]}" if len(self.empty_zones) == 1 else f" in {tuple(self.empty_zones)}"
        self.zones_layer.selectByExpression(f'"zone"{qry}', QgsVectorLayer.SetSelection)
        self.iface.mapCanvas().refresh()
        self.but_fill_empty.setEnabled(len(self.empty_zones) > 0)

    def fill_locations(self):
        geotool = Geo(self._p.path_to_file)
        with commit_and_close(self._p.path_to_file, spatial=True) as conn:
            loc_id = conn.execute("select coalesce(max(location), 0)+1 from Location").fetchone()[0]
            park = conn.execute("select coalesce(max(parking), 0)+1 from Parking").fetchone()[0]

            for i, zone in enumerate(self.empty_zones):
                p = Parking(park, self._p.geotools, self._p.tables, conn=conn)
                p.zone = zone
                p.geo = geotool.get_geo_for_id("zone", zone).centroid
                p.dir = p.offset = p.link = p.permit = p.start = p.hourly = p.daily = 0
                p.type = "location"
                p.end = 86400
                p.space = 9999
                p.save(conn)

                loc = Location(loc_id + i, self._p.geotools, self._p.tables, conn)
                loc.zone = zone
                loc.geo = geotool.get_geo_for_id("zone", zone).centroid
                loc.link = self._p.geotools.get_link_for_point_by_mode(loc.geo, ["AUTO"])
                loc.dir = loc.offset = loc.setback = loc.x = loc.y = loc.tod_distance = 0
                loc.truck_org = loc.truck_des = loc.auto_org = loc.auto_des = 1
                loc.transit = loc.area_type = loc.lu_area = loc.popsyn_region = loc.anchored = 0
                loc.avg_parking_cost = loc.stop_flag = 0
                loc.land_use = "ALL"
                loc.notes = "Automatically added to fulfill requirement of one location per zone"
                loc.save(conn)
                loc.update_location_links(conn, multiple=False, clear=False)
                loc.add_parking(conn, [p])
            conn.commit()

        from ..menu_actions import run_consistency

        self.empty_zones = []
        if self.run_consistency_after:
            run_consistency(self._PQgis)
        self.close()
