"""Area of grid cells dashboard section."""

from typing import cast

import geopandas as gpd
import matplotlib.colors as mcolors
import streamlit as st

from entropice.dashboard.plots.grids import create_grid_areas_map
from entropice.dashboard.utils.colors import get_cmap


@st.fragment
def _render_area_map(grid_gdf: gpd.GeoDataFrame):
    st.subheader("Spatial Distribution of Grid Cell Areas")

    metric = st.selectbox(
        "Metric",
        options=["cell_area", "land_area", "water_area", "land_ratio"],
        format_func=lambda x: x.replace("_", " ").title(),
        key="metric",
    )

    make_3d_map = cast(bool, st.toggle("3D Map", value=True, key="area_map_3d"))

    # Check if subsampling will occur
    n_cells = len(grid_gdf)
    if n_cells > 50000:
        st.info(f"🗺️ **Map subsampled:** Displaying 50,000 randomly selected cells out of {n_cells:,} for performance.")

    map_deck = create_grid_areas_map(grid_gdf, metric, make_3d_map)
    st.pydeck_chart(map_deck)

    # Add legend
    with st.expander("Legend", expanded=True):
        st.markdown(f"**{metric.replace('_', ' ').title()}**")

        values = grid_gdf[metric]
        vmin, vmax = values.min(), values.max()

        # Format values based on metric type
        if metric == "land_ratio":
            vmin_str = f"{vmin:.1%}"
            vmax_str = f"{vmax:.1%}"
        else:
            vmin_str = f"{vmin:.2f} km²"
            vmax_str = f"{vmax:.2f} km²"

        # Get the same colormap used in the map
        cmap = get_cmap(metric)
        # Sample 4 colors from the colormap to create the gradient
        gradient_colors = [mcolors.to_hex(cmap(i)) for i in [0.0, 0.33, 0.67, 1.0]]
        gradient_css = ", ".join(gradient_colors)

        # Create a simple gradient legend
        st.markdown(
            f'<div style="display: flex; align-items: center; margin-top: 10px; margin-bottom: 10px;">'
            f'<span style="margin-right: 10px;">{vmin_str}</span>'
            f'<div style="flex: 1; height: 20px; background: linear-gradient(to right, '
            f'{gradient_css}); border: 1px solid #ccc;"></div>'
            f'<span style="margin-left: 10px;">{vmax_str}</span>'
            f"</div>",
            unsafe_allow_html=True,
        )

        st.caption("Color intensity represents the metric value from low (purple) to high (yellow).")

        if make_3d_map:
            st.markdown("---")
            st.markdown("**3D Elevation:**")
            st.caption(
                f"Height represents normalized {metric.replace('_', ' ')} values. "
                "Rotate the map by holding Ctrl/Cmd and dragging."
            )


def render_area_information_tab(grid_gdf: gpd.GeoDataFrame):
    """Render grid cell areas and land/water distribution.

    Args:
        grid_gdf: Pre-loaded grid GeoDataFrame.

    """
    st.markdown("### Grid Cell Areas and Land/Water Distribution")

    st.markdown(
        "This visualization shows the spatial distribution of cell areas, land areas, "
        "water areas, and land ratio across the grid. The grid has been filtered to "
        "include only cells in the permafrost region (>50° latitude, <85° latitude) "
        "with >10% land coverage."
    )

    # Show summary statistics
    col1, col2, col3, col4 = st.columns(4)
    with col1:
        st.metric("Total Cells", f"{len(grid_gdf):,}")
    with col2:
        st.metric("Avg Cell Area", f"{grid_gdf['cell_area'].mean():.2f} km²")
    with col3:
        st.metric("Avg Land Ratio", f"{grid_gdf['land_ratio'].mean():.1%}")
    with col4:
        total_land = grid_gdf["land_area"].sum()
        st.metric("Total Land Area", f"{total_land:,.0f} km²")

    st.divider()

    _render_area_map(grid_gdf)
