import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error

# =================================================
# 1. LOAD DATASET
# =================================================

df = pd.read_csv("Housing.csv")

print("First 5 rows:\n", df.head())
print("\nShape:", df.shape)
print("\nData Types:\n", df.dtypes)
print("\nMissing Values:\n", df.isnull().sum())
print("\nStatistics:\n", df.describe())

# =================================================
# 2. EXPLORATORY DATA ANALYSIS
# =================================================

# Distribution of house prices
plt.hist(df["price"].dropna(), bins=30, edgecolor="black")
plt.title("Distribution of House Prices")
plt.xlabel("Price")
plt.ylabel("Frequency")
plt.show()

# Relationship between area and price
plt.scatter(df["area"], df["price"], alpha=0.5)
plt.title("Area vs House Price")
plt.xlabel("Area")
plt.ylabel("Price")
plt.show()

# =================================================
# 3. HANDLE MISSING VALUES AND ENCODE CATEGORIES
# =================================================

df = df.drop_duplicates()
df = df.dropna()

# Separate features and target
X = df.drop("price", axis=1)
y = df["price"]

# Convert categorical columns to numerical columns
X = pd.get_dummies(X, drop_first=True, dtype=int)

print("\nInput Features:\n", X.columns)
print("\nTarget: price")

# =================================================
# 4. TRAIN-TEST SPLIT
# =================================================

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# =================================================
# 5. TRAIN LINEAR REGRESSION MODEL
# =================================================

model = LinearRegression()
model.fit(X_train, y_train)

# =================================================
# 6. PREDICT HOUSE PRICES
# =================================================

y_pred = model.predict(X_test)

comparison = pd.DataFrame({
    "Actual Price": y_test.values,
    "Predicted Price": y_pred
})

print("\nActual vs Predicted Prices:\n", comparison.head(10))

# =================================================
# 7. MODEL EVALUATION
# =================================================

r2 = r2_score(y_test, y_pred)
mae = mean_absolute_error(y_test, y_pred)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))

print("\nMODEL PERFORMANCE")
print("R2 Score:", r2)
print("MAE:", mae)
print("RMSE:", rmse)

# Actual vs Predicted graph
plt.scatter(y_test, y_pred, alpha=0.6)

low = min(y_test.min(), y_pred.min())
high = max(y_test.max(), y_pred.max())

plt.plot([low, high], [low, high], "r--")

plt.xlabel("Actual House Price")
plt.ylabel("Predicted House Price")
plt.title("Actual vs Predicted House Prices")
plt.show()
