# 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 polaris.analyze.mapping.flow_lines import delaunay_assignment, desire_lines
from polaris.analyze.trip_metrics import TripMetrics
from polaris.utils.database.data_table_access import DataTableAccess
from polaris.utils.database.db_utils import read_and_close, has_table
from qgis.PyQt.QtCore import QTime
from qgis.PyQt.QtGui import QFont
from qgis.PyQt.QtWidgets import QApplication
from qgis.PyQt.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QComboBox, QLabel, QDialog, QTimeEdit, QPushButton
from qgis.core import QgsLineSymbol, QgsSimpleLineSymbolLayer
from qgis.utils import iface

from QPolaris.modules.common_tools.blocking_signals import block_signals
from QPolaris.modules.common_tools.double_slider import SingleBarDoubleSlider
from QPolaris.modules.common_tools.time_edits import QTimeEdit15Step, QTimeEdit24Step


class CommonMatrixExtractionDialog(QDialog):
    def __init__(self, _PQgis):
        super().__init__()
        self.iface = _PQgis.iface
        self.project = _PQgis
        self.__initUI__()

    def __initUI__(self):
        # Main layout
        self.setFixedSize(560, 220)
        default_font = QApplication.font()
        self.setFont(QFont(default_font.family(), 11))
        self.main_layout = QVBoxLayout()

        # Mapping type
        self.first_box = QHBoxLayout()

        # Aggregation level
        lbl2 = QLabel("Aggregation level")
        lbl2.setFixedWidth(120)
        self.aggregation = QComboBox()
        self.aggregation.addItems(["Zone", "County"])
        self.aggregation.setCurrentIndex(0)
        self.aggregation.setFixedWidth(120)

        self.first_box.addWidget(lbl2)
        self.first_box.addWidget(self.aggregation)

        self.main_layout.addLayout(self.first_box)

        # Time range
        self.slider_layout = QVBoxLayout()

        time_slider_header_layout = QHBoxLayout()

        lbl3 = QLabel("From time")
        lbl3.setMaximumWidth(120)
        self.from_time = QTimeEdit15Step()
        self.from_time.setDisplayFormat("HH:mm")
        self.from_time.setTime(QTime(0, 0))
        self.from_time.timeChanged.connect(self.on_from_time_changed)

        lbl4 = QLabel("     To time")
        lbl4.setMaximumWidth(120)
        self.to_time = QTimeEdit24Step()
        self.to_time.setDisplayFormat("HH:mm")
        self.to_time.setTime(QTime(23, 59))
        self.to_time.timeChanged.connect(self.on_to_time_changed)

        time_slider_header_layout.addWidget(lbl3)
        time_slider_header_layout.addWidget(self.from_time)
        time_slider_header_layout.addStretch()
        time_slider_header_layout.addWidget(lbl4)
        time_slider_header_layout.addWidget(self.to_time)

        self.slider_layout.addLayout(time_slider_header_layout)

        self.time_slider_layout = QHBoxLayout()

        # We will use 15 minute intervals for the slider
        self.slider_time = SingleBarDoubleSlider(0, 24 * 4 + 1)
        self.slider_time.setMaximumWidth(540)

        self.time_slider_layout.addWidget(self.slider_time)
        self.slider_layout.addLayout(self.time_slider_layout)

        self.main_layout.addLayout(self.slider_layout)

        # Execution button
        self.go = QPushButton(text="Action Button")
        self.main_layout.addWidget(self.go)

        # Set main layout
        self.setLayout(self.main_layout)

        self.slider_time.rangeChanged.connect(self.slider_time_changed)

    @block_signals
    def slider_time_changed(self, low, high):
        if high > 24 * 4:
            self.slider_time.setHighValue(24 * 4)
        if low < 0:
            self.slider_time.setLowValue(0)
            low = 0

        self.set_time_from_float(self.from_time, low / 4)
        self.set_time_from_float(self.to_time, high / 4)

    @staticmethod
    def set_time_from_float(qtimeedit, value):
        value = max(0, min(24, value))
        hours = int(value)
        minutes = int((value - hours) * 60)
        qtimeedit.setTime(QTime(hours, minutes))

    @block_signals
    def on_from_time_changed(self, qtime):
        value = int(qtime.hour() * 4 + qtime.minute() / 15)
        value_max = int(self.to_time.time().hour() * 4 + self.to_time.time().minute() / 15)
        value = min(value, value_max)
        self.slider_time.setLowValue(value)

    @block_signals
    def on_to_time_changed(self, qtime):
        value = int(qtime.hour() * 4 + qtime.minute() / 15)
        value_min = int(self.from_time.time().hour() * 4 + self.from_time.time().minute() / 15)
        value = max(value, value_min)
        value = value if value > 0 else 24 * 4

        self.slider_time.setHighValue(value)
