# Advanced demo: Call JSONPlaceholder API, fetch multiple user/posts, write/read JSON/CSV, preprocess, regress, evaluate, visualize
import requests
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
import json

def advanced_api_file_demo():
    # Call API for multiple users/posts
    users_url = "https://jsonplaceholder.typicode.com/users"
    posts_url = "https://jsonplaceholder.typicode.com/posts"
    users_response = requests.get(users_url)
    posts_response = requests.get(posts_url)
    users = users_response.json()
    posts = posts_response.json()
    # Preprocess and merge
    users_df = pd.DataFrame(users)[['id', 'name', 'username']]
    posts_df = pd.DataFrame(posts)[['userId', 'id', 'title', 'body']]
    merged_df = pd.merge(posts_df, users_df, left_on='userId', right_on='id', how='left')
    # Feature engineering
    merged_df['Title_Length'] = merged_df['title'].apply(len)
    merged_df['Body_Length'] = merged_df['body'].apply(len)
    merged_df['Name_Length'] = merged_df['name'].apply(len)
    # Write to CSV and JSON
    merged_df.to_csv('api_data.csv', index=False)
    merged_df.to_json('api_data.json', orient='records')
    # Read from files, merge
    df_csv = pd.read_csv('api_data.csv')
    with open('api_data.json', 'r') as f:
        df_json = pd.DataFrame(json.load(f))
    df_merged = pd.merge(df_csv, df_json, on=list(merged_df.columns), how='inner')
    # Prepare data for modeling
    scaler = StandardScaler()
    X = df_merged[['Title_Length', 'Body_Length', 'Name_Length']].values
    y = np.random.rand(len(df_merged)) * 100  # Synthetic target for regression demo
    X_scaled = scaler.fit_transform(X)
    # Split and model
    X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
    model = LinearRegression()
    model.fit(X_train, y_train)
    y_pred = model.predict(X_test)
    mse = mean_squared_error(y_test, y_pred)
    r2 = r2_score(y_test, y_pred)
    print(f"MSE: {mse:.2f}, R2: {r2:.2f}")
    # Visualize
    plt.figure(figsize=(8, 5))
    plt.scatter(y_test, y_pred, c='blue', alpha=0.5)
    plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'k--', lw=2)
    plt.title('JSONPlaceholder API Regression Predictions')
    plt.xlabel('True Values')
    plt.ylabel('Predictions')
    plt.annotate('Best Fit', xy=(y_test.mean(), y_pred.mean()), xytext=(y_test.mean() + 0.5, y_pred.mean() + 0.5),
                 arrowprops=dict(facecolor='black', shrink=0.05))
    plt.show()
    # Save results
    results = {'MSE': mse, 'R2': r2}
    with open('api_results.json', 'w') as f:
        json.dump(results, f)
    print("Results saved to 'api_results.json'")

advanced_api_file_demo()