




import os
import io
import chardet
import codecs


from qgis.PyQt.QtCore import Qt
from urbanq.function.qss import create_tab_style
from qgis.PyQt.QtWidgets import QComboBox, QCompleter, QApplication


from qgis.core import (
    Qgis,
    QgsMessageLog,
    QgsApplication,
    QgsAuthMethodConfig,
    QgsDataSourceUri,
    QgsSettings,
    QgsVectorLayer
)





def set_combobox_fill_list_set_value_signals(qcombobox, list_values, default_value='', use_block_signals=False):
    
    set_combobox_fill_list_signals(qcombobox, list_values, use_block_signals)  
    set_combobox_default_value_signals(qcombobox, default_value, use_block_signals)  


def set_combobox_default_value_signals(qcombobox, default_value='', use_block_signals=False):
    
    def update_combobox(w, v):
        index = w.findText(v, Qt.MatchFixedString) if v else -1  
        w.setCurrentIndex(index)

    if use_block_signals:
        action_widget_signals(qcombobox, update_combobox, default_value)
    else:
        update_combobox(qcombobox, default_value)


def set_combobox_fill_list_signals(qcombobox, list_values, use_block_signals=False):
    
    def update_combobox(w, values):
        w.clear()
        w.addItems(values)

    if use_block_signals:
        action_widget_signals(qcombobox, update_combobox, list_values)
    else:
        update_combobox(qcombobox, list_values)


def update_combobox_with_item_and_block_signals(qcombobox, item, use_block_signals=False):
    

    def update_combobox(w, v):
        current_items = [w.itemText(i) for i in range(w.count())]
        if v.lower() not in (i.lower() for i in current_items):  
            w.addItem(v)
        w.setCurrentText(v)  

    if use_block_signals:
        action_widget_signals(qcombobox, update_combobox, item)
    else:
        update_combobox(qcombobox, item)


def set_combobox_checked_list_signals(qcombobox, list_values, use_block_signals=False):
    
    if use_block_signals:
        action_widget_signals(qcombobox, lambda w, v: w.setCheckedItems(v), list_values)
        action_widget_signals(qcombobox, lambda w, v: w.setEditText(", ".join(v)), list_values)
    else:
        qcombobox.setCheckedItems(list_values)





def update_progress(qprogress, value):
    
    qprogress.setValue(value)
    QApplication.processEvents()  


def show_progress(qprogress, visible=True):
    
    if visible:
        qprogress.setVisible(True)
        QApplication.processEvents()  
    else:
        qprogress.setValue(0)  
        qprogress.setVisible(False)





def toggle_ensure_single_checkbox_signals(selected_checkbox, other_checkbox, use_block_signals=False):
    
    if selected_checkbox.isChecked():
        if use_block_signals:
            action_widget_signals(other_checkbox, lambda w, v: w.setChecked(v), False)
        else:
            other_checkbox.setChecked(False)
    else:
        if use_block_signals:
            action_widget_signals(other_checkbox, lambda w, v: w.setChecked(v), True)
        else:
            other_checkbox.setChecked(True)


def update_checkbox_signals(qcheckbox, is_check, use_block_signals=False):
    
    if use_block_signals:
        action_widget_signals(qcheckbox, lambda w, v: w.setChecked(v), is_check)
    else:
        qcheckbox.setChecked(is_check)





def qlable_update_visibility(qlabel):
    
    text = qlabel.text()
    qlabel.setVisible(bool(text and text.strip()))


def qlabel_set_link(qlabel, url):
    
    
    link_style = 'color: #fff; text-decoration: none; background-color: transparent;'

    
    qlabel.setText(f'<a href="{url}" style="{link_style}">{qlabel.text()}</a>')

    
    qlabel.setOpenExternalLinks(True)


def set_qlabel_default_value_signals(qlabel, default_value='', use_block_signals=False):
    
    if use_block_signals:
        action_widget_signals(qlabel, lambda w, v: w.setText(v), default_value)
    else:
        qlabel.setText(default_value)





def tabwidget_resize_event(qtab):
    
    def resize_event(event):
        
        total_width = qtab.width()
        
        qtab.setStyleSheet(create_tab_style(total_width))
        
        super(qtab.__class__, qtab).resizeEvent(event)
    return resize_event





def is_qtable_has_data(qtable):
    
    for row in range(qtable.rowCount()):
        for col in range(qtable.columnCount()):
            item = qtable.item(row, col)
            if item and item.text().strip():
                return True
    return False





def action_widget_signals(widget, action, *args):
    
    widget.blockSignals(True)
    action(widget, *args)
    widget.blockSignals(False)


def clear_widget_signals(widget, use_block_signals=False):
    

    def clear_action(w):
        if hasattr(w, "clear"):  
            w.clear()

    if use_block_signals:
        action_widget_signals(widget, clear_action)
    else:
        clear_action(widget)
