import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, r2_score
import matplotlib.pyplot as plt
import seaborn as sns
import requests
from io import StringIO
from datetime import datetime, timedelta

def get_climate_data():
    """Downloads historical climate data for India from Berkeley Earth"""
    url = "http://berkeleyearth.lbl.gov/auto/Regional/TAVG/Text/india-TAVG-Trend.txt"
    
    try:
        response = requests.get(url)
        data_lines = response.text.split('\n')[70:]  # Skip header
        data_text = '\n'.join(data_lines)
        
        df = pd.read_csv(StringIO(data_text), delim_whitespace=True,
                        names=['Year', 'Month', 'Temperature', 'Uncertainty'])
        
        df['Date'] = pd.to_datetime(df[['Year', 'Month']].assign(DAY=1))
        df.set_index('Date', inplace=True)
        
        return df
    except Exception as e:
        print(f"Error downloading data: {e}")
        return None

def create_features(df):
    """Create features for the model"""
    df = df.copy()
    
    # Time-based features
    df['Year'] = df.index.year
    df['Month'] = df.index.month
    df['Season'] = pd.cut(df['Month'], 
                         bins=[0, 2, 5, 8, 11, 12],
                         labels=['Winter', 'Spring', 'Summer', 'Autumn', 'Winter'])
    
    # Create lagged features
    df['Temp_1m_lag'] = df['Temperature'].shift(1)
    df['Temp_3m_lag'] = df['Temperature'].shift(3)
    df['Temp_6m_lag'] = df['Temperature'].shift(6)
    df['Temp_12m_lag'] = df['Temperature'].shift(12)
    
    # Create rolling mean features
    df['Temp_3m_mean'] = df['Temperature'].rolling(window=3).mean()
    df['Temp_6m_mean'] = df['Temperature'].rolling(window=6).mean()
    df['Temp_12m_mean'] = df['Temperature'].rolling(window=12).mean()
    
    # Add trend feature
    df['Years_from_start'] = (df.index.year - df.index.year.min())
    
    # Season-Year interaction
    df['Season_Year'] = df['Season'].astype(str) + '_' + df['Year'].astype(str)
    
    # Drop rows with NaN values
    df = df.dropna()
    
    return df

def prepare_future_features(last_data, months_to_predict):
    """Prepare feature set for future predictions"""
    future_dates = pd.date_range(
        start=last_data.index[-1] + pd.DateOffset(months=1),
        periods=months_to_predict,
        freq='M'
    )
    
    future_df = pd.DataFrame(index=future_dates)
    future_df['Year'] = future_df.index.year
    future_df['Month'] = future_df.index.month
    future_df['Years_from_start'] = (future_df.index.year - last_data.index.year.min())
    
    # Copy last known values for lagged features
    future_df['Temp_1m_lag'] = last_data['Temperature'].iloc[-1]
    future_df['Temp_3m_lag'] = last_data['Temperature'].iloc[-3:].mean()
    future_df['Temp_6m_lag'] = last_data['Temperature'].iloc[-6:].mean()
    future_df['Temp_12m_lag'] = last_data['Temperature'].iloc[-12:].mean()
    
    future_df['Temp_3m_mean'] = last_data['Temperature'].iloc[-3:].mean()
    future_df['Temp_6m_mean'] = last_data['Temperature'].iloc[-6:].mean()
    future_df['Temp_12m_mean'] = last_data['Temperature'].iloc[-12:].mean()
    
    return future_df

def train_model(df):
    """Train the prediction model"""
    features = ['Year', 'Month', 'Years_from_start',
                'Temp_1m_lag', 'Temp_3m_lag', 'Temp_6m_lag', 'Temp_12m_lag',
                'Temp_3m_mean', 'Temp_6m_mean', 'Temp_12m_mean']
    
    X = df[features]
    y = df['Temperature']
    
    # Split the data
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
    
    # Scale the features
    scaler = StandardScaler()
    X_train_scaled = scaler.fit_transform(X_train)
    X_test_scaled = scaler.transform(X_test)
    
    # Train the model
    model = RandomForestRegressor(n_estimators=100, random_state=42)
    model.fit(X_train_scaled, y_train)
    
    # Make predictions on test set
    y_pred = model.predict(X_test_scaled)
    
    return model, scaler, features, X_test, y_test, y_pred

def make_future_predictions(model, scaler, last_data, months_to_predict):
    """Make predictions for future months"""
    future_features = prepare_future_features(last_data, months_to_predict)
    
    # Scale features
    future_features_scaled = scaler.transform(future_features)
    
    # Make predictions
    future_predictions = model.predict(future_features_scaled)
    
    # Create prediction DataFrame
    predictions_df = pd.DataFrame({
        'Date': future_features.index,
        'Predicted_Temperature': future_predictions
    }).set_index('Date')
    
    return predictions_df

def plot_historical_and_predictions(historical_df, predictions_df):
    """Plot historical data and future predictions"""
    plt.figure(figsize=(15, 7))
    
    # Plot historical data
    plt.plot(historical_df.index, historical_df['Temperature'],
             label='Historical Temperature', color='blue', alpha=0.6)
    
    # Plot predictions
    plt.plot(predictions_df.index, predictions_df['Predicted_Temperature'],
             label='Predicted Temperature', color='red', linestyle='--')
    
    # Add confidence interval for predictions
    plt.fill_between(predictions_df.index,
                    predictions_df['Predicted_Temperature'] - 0.5,
                    predictions_df['Predicted_Temperature'] + 0.5,
                    color='red', alpha=0.2)
    
    plt.title('Historical Temperature Data and Future Predictions for India')
    plt.xlabel('Year')
    plt.ylabel('Temperature Anomaly (°C)')
    plt.legend()
    plt.grid(True)
    plt.show()

def main():
    # Get historical data
    print("Downloading climate data...")
    df = get_climate_data()
    
    if df is None:
        print("Failed to download data. Please check your internet connection.")
        return
    
    # Prepare features
    print("Preparing features...")
    df_featured = create_features(df)
    
    # Train model
    print("Training model...")
    model, scaler, features, X_test, y_test, y_pred = train_model(df_featured)
    
    # Calculate and print model performance metrics
    mse = mean_squared_error(y_test, y_pred)
    r2 = r2_score(y_test, y_pred)
    print(f"\nModel Performance:")
    print(f"Mean Squared Error: {mse:.4f}")
    print(f"R² Score: {r2:.4f}")
    
    # Make future predictions (e.g., for next 10 years = 120 months)
    months_to_predict = 120
    print(f"\nMaking predictions for next {months_to_predict//12} years...")
    future_predictions = make_future_predictions(
        model, scaler, df_featured, months_to_predict
    )
    
    # Plot results
    print("\nGenerating visualization...")
    plot_historical_and_predictions(df, future_predictions)
    
    # Print some prediction statistics
    print("\nPrediction Summary:")
    print(f"Average predicted temperature anomaly: {future_predictions['Predicted_Temperature'].mean():.2f}°C")
    print(f"Maximum predicted temperature anomaly: {future_predictions['Predicted_Temperature'].max():.2f}°C")
    print(f"Minimum predicted temperature anomaly: {future_predictions['Predicted_Temperature'].min():.2f}°C")
    
    # Save predictions to CSV
    future_predictions.to_csv('temperature_predictions_india.csv')
    print("\nPredictions saved to 'temperature_predictions_india.csv'")

if __name__ == "__main__":
    main()

o1, I want you to make the following changes

1. Change the source of historical data as that's not working at the moment.
2. I want you to divide India into 5 parts - North, West, South, East and Central. 
3. I want you to use matplotlib to plot the historical trends of temperature and other relevant climatic parameters for each of these zones on two scales - 
a. 5 years
b. 30 years (with indexes at every 10 years)

I then want you to use machine learning to predict the temperature and other relevant climatic parameters for these zones by the means of charts like we plotted above for historical data, but for future this time.