
import sys
fo = sys.stdout

from collections import defaultdict

import numbers

from typing import Union, Dict, Tuple

from qgis.core import QgsProject

import matplotlib.pyplot as plt


def get_symbology_field(layer) -> Union[None, str]:
    """
    Restituisce il nome del campo su cui è basata la simbologia del layer,
    se è un singolo campo; altrimenti None.
    """

    try:

        renderer = layer.renderer()
        rtype = renderer.type()

        if rtype in ("categorizedSymbol", "graduatedSymbol"):

            attr = renderer.classAttribute()

            # Controlla se 'attr' è il nome di un campo reale
            if attr in [f.name() for f in layer.fields()]:
                return attr
            else:
                return None
        else:
            return None

    except Exception as e:

        fo.write(f"\n{e!r}")
        return None


def extract_qgis_colors(layer) -> Union[None, defaultdict[str, Tuple[numbers.Real, numbers.Real, numbers.Real]]]:
    """
    Estrae le coppie (etichetta, colore) dalla simbologia di un layer QGIS,
    mantenendo l'ordine della legenda.

    :param layer: QgsVectorLayer
    :return: lista di tuple (etichetta, (R, G, B)), con RGB normalizzato [0-1]
    """

    try:

        renderer = layer.renderer()
        results = defaultdict(tuple)

        if renderer.type() == "categorizedSymbol":

            for cat in renderer.categories():
                qcolor = cat.symbol().color()
                results[cat.label()] = (qcolor.redF(), qcolor.greenF(), qcolor.blueF())

        elif renderer.type() == "graduatedSymbol":

            for rng in renderer.ranges():
                qcolor = rng.symbol().color()
                results[rng.label()] = (qcolor.redF(), qcolor.greenF(), qcolor.blueF())

        elif renderer.type() == "singleSymbol":

            qcolor = renderer.symbol().color()
            results["all features"] = (qcolor.redF(), qcolor.greenF(), qcolor.blueF())

        else:

            raise ValueError(f"Renderer type not managed: {renderer.type()}")

        return results

    except Exception as e:

        fo.write(f"\n{e!r}")
        return None


if __name__ == "__main__":

    # --- Esempio d'uso ---
    layer_name = "NomeDelTuoLayer"  # Sostituisci con il nome effettivo
    layer = QgsProject.instance().mapLayersByName(layer_name)[0]

    color_map = extract_qgis_colors(layer)

    # Stampa in ordine QGIS
    for label, color in color_map:
        print(f"{label}: {color}")

    # --- Esempio con Matplotlib ---
    labels = [lbl for lbl, _ in color_map]
    colors = [col for _, col in color_map]

    plt.bar(range(len(labels)), [1] * len(labels), color=colors)
    plt.xticks(range(len(labels)), labels, rotation=45, ha='right')
    plt.tight_layout()
    plt.show()
