#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
#    http://shiny.rstudio.com/
#

library("shiny")
library("deSolve")
library("cowplot")
library("ggplot2")
library("tidyverse")
library("ggrepel")
#library("highcharter")
library("shinydashboard")

## Create an SIR function
sir <- function(time, state, parameters) {
  with(as.list(c(state, parameters)), {
    dS <- -beta * S * I
    dI <-  beta * S * I - gamma * I
    dR <-                 gamma * I
    dV <- 0
    return(list(c(dS, dI, dR, dV)))
  })
}

# Define UI for application that draws a histogram
ui <- fluidPage(# Application title
ui <- dashboardPage(
  dashboardHeader(disable = TRUE),
   dashboardSidebar(
  #sidebarLayout(
    #     sliderInput("popsize",
    #                 "Population size:",
    #                 min = 60000,
    #                 max = 6000000,
    #                 value = 6000000),
#    sidebarPanel(
      sliderInput(
        "connum",
        "Basic reproductive number (R0, antal personer):",
        min = .5,
        max = 20,
        value = 5
      ),
      sliderInput(
        "pinf",
        "% infected at start:",
        min = 0.01,
        max = 1,
        value = 0.01
      ),
      sliderInput(
        "pvac",
        "Andel vaccinerede + tidligere immune (%):",
        min = 0,
        max = 100,
        value = 70
      ),
      sliderInput(
        "vaceff",
        "Vaccineeffektivitet (%):",
        min = 0, 
        max = 100,
        value = 80
      ),
      sliderInput(
        "infper",
        "Infektionsperiode (dage):",
        min = 1,
        max = 30,
        value = 10
      ),
      sliderInput(
        "timeframe",
        "Tidsperiode (dage):",
        min = 1,
        max = 400,
        value = 100
      )
      
    ),
    dashboardBody(
#    mainPanel(
      fluidRow(plotOutput("distPlot")),
      br(),
      fluidRow(
        # Dynamic valueBoxes
        valueBoxOutput("progressBox", width = 6),
        valueBoxOutput("approvalBox", width = 6),
        valueBoxOutput("BRRBox", width = 6),
        valueBoxOutput("HIBox", width = 6)
        
      )
    )
  )   
) 

# Define server logic required to draw a histogram
server <- function(input, output) {
  # Create reactive input
  dataInput <- reactive({
    init       <-
      c(
        S = 1 - input$pinf / 100 - input$pvac / 100 * input$vaceff / 100,
        I = input$pinf / 100,
        R = 0,
        V = input$pvac / 100 * input$vaceff / 100
      )
    ## beta: infection parameter; gamma: recovery parameter
    parameters <-
      c(beta = input$connum * 1 / input$infper,
        # * (1 - input$pvac/100*input$vaceff/100),
        gamma = 1 / input$infper)
    ## Time frame
    times      <- seq(0, input$timeframe, by = .2)
    
    ## Solve using ode (General Solver for Ordinary Differential Equations)
    out <-
      ode(
        y = init,
        times = times,
        func = sir,
        parms = parameters
      )
    
    #    out
    as.data.frame(out)
  })
  
  output$distPlot <- renderPlot({
    out <-
      dataInput() %>% 
      gather(key, value,-time) %>% 
      mutate(id = row_number(), 
             key2=recode(key, 
                         S = "Modtagelige (S)", 
                         I = "Inficerede (I)",
                         R = "Sygdomsramte (R)",
                         V = "Vaccinerede + tidligere immune"),
             keyleft=recode(key, 
                         S = "Modtagelige (S)", 
                         I = "",
                         R = "",
                         V = "Vaccinerede + tidligere immune"),
             keyright=recode(key, 
                            S = "", 
                            I = "Inficerede (I)",
                            R = "Sygdomsramte (R)",
                            V = "")
             )

    ggplot(data = out, aes(
      x = time,
      y = value,
      group = key2,
      col = key2,
      label = key2,
      data_id = id
    )) + # ylim(0, 1) +
      ylab("Procent af hele befolkningen") + xlab("Tid (dage)") +
      geom_line(size = 2) +
      geom_text_repel(
        data = subset(out, time == max(time)),
        aes(label=keyright),
        size = 6,
        segment.size  = 0.2,
        segment.color = "grey50",
        nudge_x = 0,
        hjust=1,
        direction="y"
        ) +
      geom_text_repel(
        data = subset(out, time == min(time)),
        aes(label=keyleft),
        size = 6,
        segment.size  = 0.2,
        segment.color = "grey50",
        nudge_x = 0,
        hjust=0,
        direction="y"
      ) +
      theme(legend.position = "none") +
      scale_colour_manual(values = c("red", "green4", "black", "blue")) +
      scale_y_continuous(labels = scales::percent, limits=c(0,1))
    #     scale_y_continuous(labels = function(x) paste0(x*100, "%"))
#      scale_y_continuous(labels = scales::percent)
    #+ 
#      geom_text_repel(data=out, 
#        nudge_y      = 0.05,
#        nudge_x      = dataInput() %>% summarize(maxt=max(time)) %>% pull(),
#        direction    = "x",
#        angle        = 90,
#        vjust        = 0,
#        segment.size = 0.2
#      )
    #       geom_line(aes(y=I), col="red", size=2) +
    #       geom_line(aes(y=R), col="blue", size=2) +
    #       geom_line(aes(y=V), col="green", size=2)
    #     ggiraph(code=print(g))
    #     print(g)
  })
  
  output$progressBox <- renderValueBox({
    valueBox(
      dataInput() %>% filter(time == max(time)) %>% select(R) %>% mutate(R = round(100 *
                                                                                     R, 2)) %>% paste0("%"),
      "Andel af hele populationen ramt af sygdommen",
      icon = icon("thumbs-up", lib = "glyphicon"),
      color = "black"
    )
  })
  
  output$approvalBox <- renderValueBox({
    valueBox(
      paste0(round(
        100 * (
          dataInput() %>% filter(row_number() == n()) %>% mutate(res = (R + I) / (S + I + R)) %>% pull("res")
        ), 2
      ), "%"),
      "Andel af modtagelige, der får sygdommen",
      icon = icon("thermometer-full"),
      color = "black"
    )
  })
  
  
  # Mangler af gange med N
  output$BRRBox <- renderValueBox({
    valueBox(
      paste0(round(input$connum *
                     ((1 - input$pvac / 100 * input$vaceff / 100)
                     )
                   , 2), ""),
      "Effektiv R0 (for populationen ved start)",
      icon = icon("arrows-alt"),
      color = "red"
    )
  })
  
  # Mangler af gange med N
  output$HIBox <- renderValueBox({
    valueBox(
      paste0(round(100 * (
        1 -
          1 / (input$connum 
          )), 2), "%"),
        "Andel immune nødvendigt for flokimmunitet",
        icon = icon("medkit"),
        color = "blue"
      )
  })
    
}

# Run the application
shinyApp(ui = ui, server = server)
