library(shiny)
library(ggplot2)
library(rsconnect)

# Set seed for reproducibility
set.seed(123)

# Generate synthetic data
n <- 25
X <- runif(n, 0, 10)
Y <- 1 + X + rnorm(n, sd = 4)

# Create a data frame
data <- data.frame(X = X, Y = Y)

# UI for the Shiny app
ui <- fluidPage(
  titlePanel("Polynomial Regression with OLS"),
  sliderInput("power", "Power of X:", min = 1, max = 15, value = 1),
  plotOutput("regPlot")
)

# Server logic for the Shiny app
server <- function(input, output) {
  output$regPlot <- renderPlot({
    k <- input$power
    model <- lm(Y ~ poly(X, k), data = data)
    
    # Create a dense sequence of X values for smooth predictions
    new_X <- seq(min(X), max(X), length.out = 1000)
    preds <- predict(model, newdata = data.frame(X = new_X))
    r_squared <- summary(model)$r.squared
    
    # Create a data frame with the new X values and predicted Y values
    pred_data <- data.frame(X = new_X, Y = preds)
    
    # Show the full fitted curve, including oscillations beyond the observed range
    y_min <- min(data$Y, preds)
    y_max <- max(data$Y, preds)
    
    gg <- ggplot(data, aes(x = X, y = Y)) + 
      geom_point(alpha = 0.25) + 
      geom_line(data = pred_data, aes(x = X, y = Y), color = 'red') +
      labs(title = paste("Polynomial Regression with Power", k), x = "X", y = "Y") +
      annotate("text", x = min(X), y = y_max, label = paste("R^2 =", round(r_squared, 3)),
               vjust = -1, hjust = 0.5) +
      coord_cartesian(ylim = c(y_min, y_max)) +
      theme_minimal()
    print(gg)
  })
}

# Run the Shiny app
shinyApp(ui = ui, server = server)
