library(shiny)
library(bslib)
library(ggplot2)
library(patchwork)

simulateData <- function(n, mu, sigma, phi) {
  
  burnin <- 100
  
  burnin_t <- n + burnin
  
  innov_var <- sigma * (1 - phi ^ 2)

  e <- rnorm(burnin_t, sd = sqrt(innov_var))
  y <- numeric(burnin_t)
  
  for (t in 2:burnin_t) {
    y[t] <- mu + phi * (y[t - 1] - mu) + e[t]
  }
  
  y <- y[(burnin + 1):burnin_t]
  
  dat <- data.frame(y = y, t = 1:n)
  
  return(dat)
  
}

plotTimeSeries <- function(dat, plot_widths = c(2, 5, 1)) {
  
  x_breaks <- pretty(1:nrow(dat))

  y_breaks <- pretty(dat$y)
  y_lim <- c(min(y_breaks), max(y_breaks))

  axis_line_width <- 0.3
  
  dat$y_lag <- c(NA, dat$y[-length(dat$y)])
  
  coryy <- round(cor(dat$y,  dat$y_lag, use = "complete.obs"), 3)
  meany <- mean(dat$y)
  
  lm1 <- lm(y ~ y_lag, dat)
  ys1 <- cbind(1, c(min(y_breaks), max(y_breaks))) %*% coef(lm1)

  p_ss <- ggplot(dat, aes(x = y_lag, y = y)) +
    geom_segment(aes(x = min(y_breaks), xend = max(y_breaks),
                     y = ys1[1], yend = ys1[2]),
                 linewidth = 0.3, colour = "gray") +
    geom_point(size = 2, shape = 21, fill = "white") +
    scale_y_continuous(breaks = y_breaks) +
    scale_x_continuous(breaks = y_breaks) +
    coord_cartesian(ylim = y_lim, xlim = y_lim) +
    theme_void() +
    labs(x = bquote(y[t-1]), y = bquote(y[t])) +
    theme(text = element_text(family = "sans", size = 16),
          axis.text = element_text(margin = margin(5, 5, 5, 5)),
          axis.title = element_text(margin = margin(5, 5, 5, 5)),
          axis.ticks = element_line(lineend = "butt",
                                    linewidth = axis_line_width),
          axis.ticks.length = unit(2.5, "pt"),
          panel.spacing = unit(5, units = "pt"),
          plot.margin = margin(0, 5, 0, 0),
          legend.position = "none") +
    geom_segment(x = -Inf, xend = -Inf, y = y_breaks[1],
                 yend = y_breaks[length(y_breaks)],
                 linewidth = axis_line_width, lineend = "square") +
    geom_segment(y = -Inf, yend = -Inf, x = y_breaks[1],
                 xend = y_breaks[length(y_breaks)],
                 linewidth = axis_line_width, lineend = "square") +
    annotate("text", x = -Inf, y = Inf, hjust = -0.2, vjust = 2,
             label = bquote(hat(rho)[1]~"="~.(coryy)), size = 5)
  
  p_ts <- ggplot(dat) + 
    geom_segment(x = x_breaks[1], xend = max(x_breaks), y = meany, yend = meany,
                 linewidth = 0.3, colour = "gray") +
    geom_line(aes(x = t, y = y)) +
    geom_point(aes(x = t, y = y), size = 2, shape = 21, fill = "white") +
    scale_y_continuous(breaks = y_breaks) +
    scale_x_continuous(breaks = x_breaks) +
    coord_cartesian(ylim = y_lim, xlim = c(min(x_breaks), max(x_breaks))) +
    theme_void() +
    labs(x = "t") + 
    theme(text = element_text(family = "sans", size = 16),
          axis.text.x = element_text(margin = margin(5, 5, 5, 5)),
          axis.title.x = element_text(margin = margin(5, 5, 5, 5)),
          axis.ticks = element_line(lineend = "butt",
                                    linewidth = axis_line_width),
          axis.ticks.length = unit(2.5, "pt"),
          panel.spacing = unit(5, units = "pt"),
          plot.margin = margin(0, 5, 0, 0),
          legend.position = "none") +
    geom_segment(x = -Inf, xend = -Inf, y = y_breaks[1], yend = max(y_breaks),
                 linewidth = axis_line_width, lineend = "square") +
    geom_segment(y = -Inf, yend = -Inf, x = x_breaks[1], xend = max(x_breaks),
                 linewidth = axis_line_width, lineend = "square")
  
  p_hist <- ggplot(dat) + 
    geom_histogram(aes(y = y, x = ..density..), fill = "gray", colour = "black") +
    geom_density(aes(y = y)) +
    geom_hline(yintercept = meany, colour = "gray", linewidth = 0.5) +
    scale_y_continuous(breaks = y_breaks) +
    scale_x_continuous(breaks = x_breaks) +
    coord_cartesian(ylim = y_lim) +
    theme_void() +
    labs(x = "", y = "") +
    theme(text = element_text(family = "sans", size = 16),
          axis.title = element_text(margin = margin(5, 5, 5, 5)),
          panel.spacing = unit(5, units = "pt"),
          plot.margin = margin(0, 5, 0, 0))
  
  p <- p_ss + p_ts + p_hist + plot_layout(widths = plot_widths)
  
  return(p)
  
}

ui <- fluidPage(
  fluidRow(
    column(3,
      numericInput("n", label = h4("Number of occasions T"), value = 100,
                   min = 10, max = 1e5, step = 10)
    ),
    column(3,
           numericInput("mean", label = HTML("<h4>Mean &mu;</h4>"), value = 0, step = 1)
    ),
    
    column(3,
           numericInput("var", label = HTML("<h4>Variance &sigma;<sup>2</sup><sub style='position: relative; left: -0.4em;'>y</sub></h4>"),
                        value = 1, min = 0, max = 100, step = 1)
    ),
    
    column(3,
           sliderInput("autoregression", label = HTML("<h4>Autoregression \U03D5<sub>1</sub></h4>"), min = -0.999, 
                       max = 0.999, value = 0.3, step = 0.05)
    )
  ),
  
  actionButton("refresh", "Refresh"),
  
  plotOutput(outputId = "main_plot", height = "250px"),
  
)

server <- function(input, output) {
  
  dat <- reactive({
    input$refresh  # include to make it reactive to the button
    simulateData(input$n, input$mean, input$var, input$autoregression)
  })
  
  output$main_plot <- renderPlot({
    
    plotTimeSeries(dat())
    
  })
  
}

shinyApp(ui = ui, server = server)