from holoviz_utils.deckgl import DeckGLPane, MVTLayer, GeoJsonLayer, ColorSelection
from holoviz_utils.sharer import share
import panel as pn
import param

if __name__ == "__main__":

    mvt_lyr = MVTLayer(
        data="https://storage.googleapis.com/fao-cog-data/basins/TO_BE_TILED/{z}/{x}/{y}.pbf",
        lineWidthMinPixels=1,
        pickable=True,
        uniqueIdProperty="basin_id",
        getLineColor="@@=[27, 70, 70, 255]",
        getFillColor=ColorSelection(
            selection_type="contains",
            trigger_type="hover",
            selection_prop="id",
            containing_prop="downstream_from",
            auto_switch_trigger_type=True,
            auto_zoom=True,
        ),
    )

    geojson_lyr = GeoJsonLayer(
        data="https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_admin_0_scale_rank.geojson",
        getLineColor=[60, 60, 60, 50],
        getFillColor=ColorSelection(
            selection_type="simple",
            trigger_type="hover",
            selection_prop="sr_sov_a3",
            auto_switch_trigger_type=True,
            auto_zoom=True,
        ),
        pickable=False,
        lineWidthMinPixels=2,
    )

    layers = [geojson_lyr, mvt_lyr]

    class DeckGL(param.Parameterized):

        map_pane = param.ClassSelector(class_=DeckGLPane)

        layers = param.List(default=[], allow_refs=True, nested_refs=True)

        initial_view_state = param.Dict()

        def __init__(self, **params):
            super().__init__(**params)

            self.search_ivs()
            
            self.map_pane = DeckGLPane(
                initial_view_state=self.initial_view_state,
                layers=[x.param["json_dict"] for x in self.layers],
                views="MapView",
                sizing_mode="stretch_both",
            )

            self.view = self.make_view()

        def search_ivs(self):
            ivss = list()
            for lyr in self.layers:
                if isinstance(lyr, param.Parameterized):
                    for key in [x for x in lyr.param if x == "ivs"]:
                        ivss.append(getattr(lyr, key))
            self.param.update(
                initial_view_state=ivss[0] if len(ivss) > 0 else {}
            )

        def make_view(self):

            column = [
                self.map_pane.param["views"],
                self.map_pane.param["tooltip_format"],
                self.map_pane.param["parse_geometry"],
            ]

            for lyr in self.layers:
                if isinstance(lyr, param.Parameterized):
                    for key in [x for x in lyr.param if isinstance(getattr(lyr, x), param.Parameterized) and lyr.pickable]:
                        column.append(getattr(lyr, key).param)

            column.append(pn.pane.JSON(self.map_pane.param["click_state"]))

            view = pn.Row(
                self.map_pane,
                pn.Column(
                    *column
                ),
            )

            return view


    dgl = DeckGL(layers=layers)

    share(dgl.view, __name__, globals().get("__file__", ""), 0)