import pandas as pd
import altair as alt
import solara
from solara.website.utils import apidoc
# Load the river data
file_path = 'merged_river_data.csv'  # Ensure the path is correct on py.cafe
river_data = pd.read_csv(file_path)
# Convert ForecastData from string representation of lists to actual lists
river_data['ForecastData'] = river_data['ForecastData'].apply(eval)
# Convert RiverNumber to string for compatibility
river_data['RiverNumber'] = river_data['RiverNumber'].astype(str)
# Determine the bounds of the map based on the river points
min_lat, max_lat = river_data['XCoordinate'].min(), river_data['XCoordinate'].max()
min_lon, max_lon = river_data['YCoordinate'].min(), river_data['YCoordinate'].max()
center_lat = (min_lat + max_lat) / 2
center_lon = (min_lon + max_lon) / 2
# Create a map chart using Altair
background = alt.Chart(alt.topo_feature('https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json', 'countries')).mark_geoshape(
    fill='lightgray',
    stroke='white'
).properties(
    width=800,
    height=400
).project(
    'mercator',
    center=[center_lon, center_lat],
    scale=500  # Adjust the scale for zoom level
)
points = alt.Chart(river_data).mark_circle(
    size=10,
    color='steelblue',
    opacity=0.8
).encode(
    longitude='YCoordinate:Q',
    latitude='XCoordinate:Q',
    tooltip=['RiverNumber:N', 'Name:N', 'Description:N']
)
map_chart = background + points
@solara.component
def Page():
    click_data, set_click_data = solara.use_state({})
    hover_data, set_hover_data = solara.use_state({})
    def convert_to_dataframe(data):
        if data:
            relevant_keys = ["RiverNumber", "Name", "XCoordinate", "YCoordinate"]
            filtered_data = {key: [data.get(key, '')] for key in relevant_keys}
            return pd.DataFrame(filtered_data)
        return pd.DataFrame()
    click_df = convert_to_dataframe(click_data)
    hover_df = convert_to_dataframe(hover_data)
    def create_forecast_chart(river_number):
        forecast_data = river_data[river_data['RiverNumber'] == river_number]['ForecastData'].values[0]
        forecast_df = pd.DataFrame({
            'Date': pd.date_range(start='2021-01-01', periods=len(forecast_data), freq='D'),
            'Flow': forecast_data
        })
        forecast_df['RiverWatch'] = forecast_df['Flow'].rolling(window=7, min_periods=1).mean()
        base = alt.Chart(forecast_df).encode(
            x='Date:T'
        )
        area = base.mark_area(
            color='black',
            opacity=1.0
        ).encode(
            y='Flow:Q'
        )
        line_river_watch = base.mark_line(
            color='green'
        ).encode(
            y='RiverWatch:Q'
        )
        line_1_5yr = alt.Chart(pd.DataFrame({
            'Date': forecast_df['Date'],
            'Threshold': [1500] * len(forecast_df)
        })).mark_rule(
            color='magenta'
        ).encode(
            y='Threshold:Q'
        )
        line_10yr = alt.Chart(pd.DataFrame({
            'Date': forecast_df['Date'],
            'Threshold': [2000] * len(forecast_df)
        })).mark_rule(
            color='red',
            strokeDash=[5, 5]
        ).encode(
            y='Threshold:Q'
        )
        line_25yr = alt.Chart(pd.DataFrame({
            'Date': forecast_df['Date'],
            'Threshold': [2500] * len(forecast_df)
        })).mark_rule(
            color='red'
        ).encode(
            y='Threshold:Q'
        )
        chart = alt.layer(area, line_river_watch, line_1_5yr, line_10yr, line_25yr).properties(
            width=800,
            height=400,
            title=f"Forecast Data for River {river_number}"
        ).interactive()
        return chart
    with solara.Div() as main:
        solara.AltairChart(map_chart, on_click=set_click_data, on_hover=set_hover_data)
        solara.Markdown("### Click data:")
        if not click_df.empty:
            solara.DataFrame(click_df)
        else:
            solara.Markdown("No data")
        if 'RiverNumber' in click_data:
            solara.Markdown("### Forecast Data:")
            forecast_chart = create_forecast_chart(click_data['RiverNumber'])
            solara.AltairChart(forecast_chart)
        else:
            solara.Markdown("### Forecast Data: Click on a river point to view forecast data")
    return main
# This is for documentation purposes
doc = apidoc(solara.AltairChart)  # type: ignore