import argparse
import pandas as pd
import plotly.graph_objects as go
import osmnx as ox

import folium
import plotly.offline as offline
from folium import plugins

# 2020 https://www.ign.es/web/ign/portal/sis-catalogo-terremotos/-/catalogo-terremotos/searchTerremoto?latMin=27&latMax=30&longMin=-19&longMax=-13&startDate=01/01/2020&endDate=31/12/2020&selIntensidad=N&selMagnitud=N&intMin=&intMax=&magMin=&magMax=&selProf=N&profMin=&profMax=&fases=no&cond=
# 2021 https://www.ign.es/web/ign/portal/sis-catalogo-terremotos/-/catalogo-terremotos/searchTerremoto?latMin=27&latMax=30&longMin=-19&longMax=-13&startDate=01/01/2021&endDate=31/12/2021&selIntensidad=N&selMagnitud=N&intMin=&intMax=&magMin=&magMax=&selProf=N&profMin=&profMax=&fases=no&cond=
# 2022 https://www.ign.es/web/ign/portal/sis-catalogo-terremotos/-/catalogo-terremotos/searchTerremoto?latMin=27&latMax=30&longMin=-19&longMax=-13&startDate=01/01/2022&endDate=31/12/2022&selIntensidad=N&selMagnitud=N&intMin=&intMax=&magMin=&magMax=&selProf=N&profMin=&profMax=&fases=no&cond=
# 2023 https://www.ign.es/web/ign/portal/sis-catalogo-terremotos/-/catalogo-terremotos/searchTerremoto?latMin=27&latMax=30&longMin=-19&longMax=-13&startDate=01/01/2023&endDate=31/12/2023&selIntensidad=N&selMagnitud=N&intMin=&intMax=&magMin=&magMax=&selProf=N&profMin=&profMax=&fases=no&cond=

#USE_SLIDER = "byweeks"
USE_SLIDER = "alldata"

# Canarias
# xlon_min, xlon_max, xticks = -19.0, -13.0, 0.5
# ylat_min, ylat_max, yticks = 27.0, 30.0, 0.5
canary_coords = {	"north": 30,	"south": 27,	"east": -13,	"west": -19}

# xlon_min, xlon_max, xticks = -16.40, -16.00, 0.04
# ylat_min, ylat_max, yticks = 27.85, 28.25, 0.04
atlantico_coords = {	"north": 28.25,	"south": 27.85,	"east": -16.00,	"west": -16.40}

# xlon_min, xlon_max, xticks = -16.90, -15.90, 0.1
# ylat_min, ylat_max, yticks = 27.75, 28.75, 0.1
# Tenerife
tenerife_coords = {	"north": 28.75,	"south": 27.75,	"east": -15.90,	"west": -16.90}

# xlon_min, xlon_max, xticks = -17.0, -16.0, 0.1
# ylat_min, ylat_max, yticks = 27.5, 28.5, 0.1
tf_atl_coords = {	"north": 29.0,	"south": 27.0,	"east": -15.5,	"west": -17.5}

# xlon_min, xlon_max, xticks = -16.80, -16.40, 0.04
# ylat_min, ylat_max, yticks = 28.00, 28.40, 0.04
tf_teide_coords = {	"north": 28.5,	"south": 28.0,	"east": -16.5,	"west": -17.0}

# Gran Canaria
gran_canaria_coords = {	"north": 28.2054,	"south": 27.9638,	"east": -15.3319,	"west": -15.7513}

# Lanzarote
lanzarote_coords = {	"north": 29.0525,	"south": 28.8084,	"east": -13.3586,	"west": -13.9594}

# Fuerteventura
fuerteventura_coords = {	"north": 28.7718,	"south": 28.0079,	"east": -13.3301,	"west": -14.4362}

# La Palma
#    xlon_min, xlon_max, xticks = -18.00, -17.70, 0.05
# ylat_min, ylat_max, yticks = 28.30, 28.80, 0.05
la_palma_coords = {	"north": 28.80,	"south": 28.30,	"east": -17.70,	"west": -18.00}

# La Gomera
la_gomera_coords = {	"north": 28.2141,	"south": 27.9633,	"east": -17.0864,	"west": -17.3375}

# El Hierro
el_hierro_coords = {	"north": 27.8375,	"south": 27.6327,	"east": -17.8837,	"west": -18.1495}
el_hierro_coords = {	"north": 28.0000,	"south": 27.5000,	"east": -17.7500,	"west": -18.2500}

points_el_hierro = [ ]

points_la_palma = [
	{
		"name": "LP (Tazacorte)",
		"latitude": 28.6427,
		"longitude": -17.9331
	},
	{
		"name": "LP (Los Cananos)",
		"latitude": 28.4936,
		"longitude": -17.8451
	},
	{
		"name": "LP (St Cruz de la Palma)",
		"latitude": 28.6871,
		"longitude": -17.7691
	},
]

tf_in_range = [
	{
		"name": "Teide",
		"latitude": 28.2739,
		"longitude": -16.6351
	},
	{
		"name": "Pico Viejo",
		"latitude": 28.2353,
		"longitude": -16.6450
	},
	{
		"name": "Adeje",
		"latitude": 28.1225,
		"longitude": -16.7380
	},
	{
		"name": "Guía de Isora",
		"latitude": 28.2058,
		"longitude": -16.8117
	},
	{
		"name": "Vilaflor",
		"latitude": 28.1563,
		"longitude": -16.6347
	},
	{
		"name": "Arona",
		"latitude": 28.1039,
		"longitude": -16.6807
	},
	{
		"name": "Santiago del Teide",
		"latitude": 28.2615,
		"longitude": -16.8178
	},
	{
		"name": "Santa Cruz de Tenerife",
		"latitude": 28.4680,
		"longitude": -16.2550
	},
	{
		"name": "La Laguna",
		"latitude": 28.4890,
		"longitude": -16.3160
	},
	{
		"name": "Candelaria",
		"latitude": 28.3760,
		"longitude": -16.3650
	},
	{
		"name": "Arico",
		"latitude": 28.2080,
		"longitude": -16.4550
	},
	{
		"name": "Granadilla de Abona",
		"latitude": 28.0440,
		"longitude": -16.5700
	},
	{
		"name": "Fasnia",
		"latitude": 28.2150,
		"longitude": -16.3900
	},
	{
		"name": "Tegueste",
		"latitude": 28.5060,
		"longitude": -16.3580
	},
	{
		"name": "Bajamar",
		"latitude": 28.5260,
		"longitude": -16.3600
	}
]


island_coordinates = {
	"atlantico": atlantico_coords,
	"canary": canary_coords,
	"tenerife": tenerife_coords,
	"tf_atl": tf_atl_coords,
	"tf_teide": tf_teide_coords,
	"gran_canaria": gran_canaria_coords,
	"lanzarote": lanzarote_coords,
	"fuerteventura": fuerteventura_coords,
	"la_palma": la_palma_coords,
	"la_gomera": la_gomera_coords,
	"el_hierro": el_hierro_coords
}

points_coordinates = {
	"atlantico": tf_in_range,
	"tenerife": tf_in_range,
	"tf_teide": tf_in_range,
	"tf_atl": tf_in_range,
	"canary": tf_in_range,
	"la_palma": points_la_palma,
	"el_hierro": points_el_hierro
}


# Function to read GPS data from CSV file and return a DataFrame
def read_gps_data(csv_file):
	df = pd.read_csv(csv_file, delimiter=';')
	return df

# Main function to generate the interactive 3D scatter plot with a timeline slider
def plot_3d_earthquakes(gps_data, chosen_coords, points_coords):

	# Convert date strings to Python datetime objects
	gps_data['Datetime'] = pd.to_datetime(gps_data['Fecha'], format='%d/%m/%Y') + pd.to_timedelta(gps_data['Hora'])
	# Reverse the depth values by multiplying by -1
	gps_data['Prof. (Km)'] = gps_data['Prof. (Km)'] * -1.0

	# Filter GPS data based on chosen_coords range
	#filtered_gps_data = gps_data[
	#	(gps_data['Longitud'] >= chosen_coords['west']) &
	#	(gps_data['Longitud'] <= chosen_coords['east']) &
	#	(gps_data['Latitud'] >= chosen_coords['south']) &
	#	(gps_data['Latitud'] <= chosen_coords['north'])
	#]
	filtered_gps_data = gps_data[
		(gps_data['Prof. (Km)'] >= args.maxdepth) &
		(gps_data['Prof. (Km)'] <= args.mindepth) &
		(gps_data['Longitud'] >= chosen_coords['west']) &
		(gps_data['Longitud'] <= chosen_coords['east']) &
		(gps_data['Latitud'] >= chosen_coords['south']) &
		(gps_data['Latitud'] <= chosen_coords['north'])
	]
	min_date = filtered_gps_data['Datetime'].min()
	max_date = filtered_gps_data['Datetime'].max()
	print("filtered_gps_data:", len(filtered_gps_data), "min:", min_date, "max:", max_date)
	#print(filtered_gps_data)
	# Print the number of unique dates after filtering

	if len(filtered_gps_data) < 25:
		print("not enough datapoints")
		return

	#unique_dates = filtered_gps_data['Datetime'].unique()
	#print("Number of unique dates after filtering:", len(unique_dates))
	yearly_data = {}
	for date, group in filtered_gps_data.groupby(filtered_gps_data['Datetime'].dt.year):
		year = str(date)
		yearly_data[year] = group.to_dict(orient='records')

	#print(yearly_data)

	# Create the "All Dates" slider step
	all_data_slider_step = dict(
		label="All Dates",
		method="update",
		args=[{"visible": True}],
	)

	#year = "2023"

	# Create the slider steps for unique dates
	slider_by_alldata = dict(
		currentvalue={"prefix": "Date: "},
		steps=[
			all_data_slider_step
		],
		active=0,
		pad={"t": 25},
	)

	# Split the unique dates into weeks
	#start_date = unique_dates.min()
	#end_date = unique_dates.max()
	#weeks = pd.date_range(start_date, end_date, freq='W-MON')  # Split by weeks starting on Monday
	#Create slider steps based on the weeks
	#weeks_slider_steps = [
	#	#for week in weeks
	#	dict(label=str(week.date()), method="update", args=[{"visible": (filtered_gps_data['Datetime'] >= week) & (filtered_gps_data['Datetime'] < (week + pd.DateOffset(weeks=1)))}])
	#	for week in weeks
	#]
	#slider_by_week = dict(
	#	currentvalue={"prefix": "Date: "},
	#	steps=weeks_slider_steps,
	#	active=0,
	#	pad={"t": 25},
	#)
	#print("Numbers of weeks:", len(weeks))
	#print("Weekslider of weeks:", weeks_slider_steps)
	#print("Weekslider:", slider_by_week)

	if USE_SLIDER == "byweeks":
		active_slider = slider_by_week
	if USE_SLIDER == "alldata":
		active_slider = slider_by_alldata

	# Create the 3D scatter plot
	fig = go.Figure()

	fig.add_trace(
		go.Scatter3d(
			x=filtered_gps_data['Longitud'],
			y=filtered_gps_data['Latitud'],
			z=filtered_gps_data['Prof. (Km)'],
			mode='markers',
			marker=dict(
				size=3,
				color=filtered_gps_data['Mag.'],
				colorscale='viridis',
				opacity=0.6,
				colorbar=dict(title='Magnitude')
			),
			text=filtered_gps_data['Evento']
		)
	)

	# Add points_coords as markers at height 0
	for point in points_coords:
		fig.add_trace(
			go.Scatter3d(
				x=[point['longitude']],
				y=[point['latitude']],
				z=[0],  # Height 0
				mode='markers+text',
				marker=dict(
					size=2,
					color='red',  # You can choose a color for the markers
					symbol='circle',  # You can choose a marker symbol
				),
				text=point['name'],
				name=point['name']
			)
		)

	# Set axis labels and scene settings
	fig.update_layout(
		scene=dict(
			xaxis_title='Longitude',
			yaxis_title='Latitude',
			zaxis_title='Depth (km)',
			camera = dict(
				eye=dict(x=-1.25, y=-1.25, z=2.0),  # Set the initial viewpoint
				up=dict(x=0, y=0, z=1),           # Set the up direction
				center=dict(x=0, y=0, z=0),       # Set the center point of the view
				projection=dict(type='perspective')  # Use a perspective projection
			),
			bgcolor='rgba(0,0,0,0)' # Set the background color

		),
		sliders=[
			active_slider
		],
	)

	# Add steps for each year in the yearly_data dictionary
	for year, data_list in yearly_data.items():
		if year != args.year:
			print("ignore entry !THIS_YEAR")
			continue

		slider_by_alldata['steps'].append(
			dict(
				label=f"Year {year}",
				method="update",
				args=[{"visible": False}, {"visible": [False] * len(fig.data)}, {"visible": True, "name": f"Year {year}", "marker.color": 'rgba(0, 0, 0, 0)'}],
				#args2=[data_list]
			)
		)

	layout = go.Layout(
		title=args.island + " " + args.year + " (" + str(args.mindepth) + " to " + str(args.maxdepth) + "KM ) Data Points:" + str(len(filtered_gps_data)),
		#width=1920,  # Adjust the width of the chart
		#height=1080,  # Adjust the height of the chart
		showlegend=False,
		#xaxis_tickvals=0.25,
		#yaxis_tickvals=0.25,
	)
	fig.update_layout(layout)

	#offline.plot(fig, filename="test/"+args.island+"."+year+".html", auto_open=False)
	#fig.show()
	#m = folium.Map(location=[27.5, -16], zoom_start=5)
	#folium.Marker([27.5, -16], tooltip='Marker').add_to(m)
	#map_iframe = folium.Element()
	#map_iframe.add_to(m)
	#map_iframe.add_to(fig)
	#offline.plot(m, filename="test/"+args.island+"."+year+".html", auto_open=False)

	fn = "html/html/"+args.island+"."+args.year+".d="+str(args.mindepth)+"_"+str(args.maxdepth)+"km.html"
	fig.write_html(fn)

if __name__ == "__main__":
	parser = argparse.ArgumentParser(description='earthquakes')
	parser.add_argument('--island', choices=island_coordinates.keys(), default='canary', help='Choose an island for visualization')
	parser.add_argument('--year', default='2023', help='select year')
	parser.add_argument('--mindepth', type=float, default=0.0, help='min depth: 0')
	parser.add_argument('--maxdepth', type=float, default=-100.0, help='max depth: -100')
	args = parser.parse_args()

	chosen_coords = island_coordinates[args.island]
	points_coords = points_coordinates[args.island]
	THIS_YEAR = args.year
	print("Chosen Island:", args.island)
	print("Chosen Coordinates:", chosen_coords)
	print("Chosen Year:", args.year)
	print("Chosen Depth:", args.mindepth, args.maxdepth, " KM")

	# Replace 'your_file.csv' with the path to your actual CSV file
	csv_file = "csv/"+THIS_YEAR+'.csv'
	gps_data = read_gps_data(csv_file)
	plot_3d_earthquakes(gps_data, chosen_coords, points_coords)
