library(shiny)

# ===============================
# FUNCTIONS (ALL TASKS)
# ===============================

# Task 3.1
identify_variables <- function(data){
  numeric_vars <- names(data)[sapply(data, is.numeric)]
  categorical_vars <- names(data)[sapply(data, function(x) is.factor(x) | is.character(x))]
  
  cat("=== Variable Types ===\n")
  cat("Numeric:\n"); print(numeric_vars)
  cat("Categorical:\n"); print(categorical_vars)
}

# Task 3.2
impute_missing <- function(data){
  
  mode_function <- function(x){
    ux <- unique(x)
    ux[which.max(tabulate(match(x, ux)))]
  }
  
  cat("\n=== Missing Values ===\n")
  
  for(col in names(data)){
    missing_count <- sum(is.na(data[[col]]))
    cat(col, ":", missing_count, "\n")
    
    if(is.numeric(data[[col]])){
      data[[col]][is.na(data[[col]])] <- mean(data[[col]], na.rm = TRUE)
    } else {
      data[[col]][is.na(data[[col]])] <- mode_function(data[[col]])
    }
  }
  
  return(data)
}

# Task 3.3
detect_outliers <- function(data, method = "IQR"){
  
  cat("\n=== Outliers (", method, ") ===\n")
  
  for(col in names(data)){
    
    if(is.numeric(data[[col]])){
      
      cat("\n", col, ":\n")
      
      if(method == "IQR"){
        Q1 <- quantile(data[[col]], 0.25)
        Q3 <- quantile(data[[col]], 0.75)
        IQR_val <- Q3 - Q1
        
        outliers <- data[[col]][
          data[[col]] < (Q1 - 1.5*IQR_val) |
            data[[col]] > (Q3 + 1.5*IQR_val)
        ]
        
      } else {
        z <- (data[[col]] - mean(data[[col]])) / sd(data[[col]])
        outliers <- data[[col]][abs(z) > 3]
      }
      
      print(outliers)
    }
  }
}

# Task 3.5 (FIXED VERSION)
run_model <- function(data, response){
  
  cat("\n=== Predictive Model ===\n")
  
  if(is.numeric(data[[response]])){
    
    cat("Model: Linear Regression\n")
    
    model <- lm(as.formula(paste(response, "~ .")), data = data)
    
    # SAFE STEPWISE (FIX)
    model <- tryCatch(
      step(model, direction = "both"),
      error = function(e){
        cat("Stepwise failed → using full model\n")
        return(model)
      }
    )
    
    print(summary(model))
    
  } else {
    
    cat("Model: Logistic Regression\n")
    
    model <- glm(as.formula(paste(response, "~ .")),
                 data = data,
                 family = "binomial")
    
    print(summary(model))
  }
}

# ===============================
# SHINY UI
# ===============================

ui <- fluidPage(
  
  titlePanel("Data Analysis Dashboard"),
  
  sidebarLayout(
    
    sidebarPanel(
      
      fileInput("file", "Upload CSV File"),
      
      textInput("response", "Enter Response Variable"),
      
      selectInput("method", "Outlier Method",
                  choices = c("IQR", "Z"))
    ),
    
    mainPanel(
      verbatimTextOutput("summary")
    )
  )
)

# ===============================
# SHINY SERVER
# ===============================

server <- function(input, output){
  
  data <- reactive({
    req(input$file)
    read.csv(input$file$datapath)
  })
  
  output$summary <- renderPrint({
    
    df <- data()
    
    identify_variables(df)
    df <- impute_missing(df)
    detect_outliers(df, input$method)
    
    if(input$response != ""){
      run_model(df, input$response)
    }
  })
}

# ===============================
# RUN APP
# ===============================

shinyApp(ui, server)
Shiny applications not supported in static R Markdown documents