import math 

class SimpleLinearRegression:
    """
    A simple linear regression model built from scratch without NumPy.
    Equation: y = b0 + b1 * x
    """

    def __init__(self):
        self.b0 = 0  # Intercept
        self.b1 = 0  # Slope
        self.is_fitted = False

    def fit(self, X, y):
        """Fit the regression model to the data."""
        n = len(X)
        mean_x = sum(X) / n
        mean_y = sum(y) / n

        # Calculate slope (b1) and intercept (b0)
        numerator = sum((X[i] - mean_x) * (y[i] - mean_y) for i in range(n))
        denominator = sum((X[i] - mean_x) ** 2 for i in range(n))
        self.b1 = numerator / denominator
        self.b0 = mean_y - self.b1 * mean_x
        self.is_fitted = True

    def predict(self, X):
        """Predict target values for a list of inputs."""
        if not self.is_fitted:
            raise Exception("Model is not fitted yet. Call fit() first.")
        return [self.b0 + self.b1 * x for x in X]

    def evaluate(self, X, y):
        """Return MAE, MSE, RMSE, and R²."""
        y_pred = self.predict(X)
        n = len(y)

        mae = sum(abs(y[i] - y_pred[i]) for i in range(n)) / n
        mse = sum((y[i] - y_pred[i]) ** 2 for i in range(n)) / n
        rmse = mse ** 0.5
        ss_tot = sum((y[i] - (sum(y) / n)) ** 2 for i in range(n))
        ss_res = sum((y[i] - y_pred[i]) ** 2 for i in range(n))
        r2 = 1 - (ss_res / ss_tot)
        return {"MAE": mae, "MSE": mse, "RMSE": rmse, "R2": r2}

    def __repr__(self):
        return f"SimpleLinearRegression(b0={self.b0:.3f}, b1={self.b1:.3f})"
