#
# 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/
#

#################   LOAD THE REQUIRED PACKAGES   #################
suppressPackageStartupMessages(library(shiny))
suppressPackageStartupMessages(library(shinyjs))
suppressPackageStartupMessages(library(shinythemes))
suppressPackageStartupMessages(library(randomForest))

httr::set_config(httr::config(http_version = 0))

# Define UI for application that draws a histogram
ui <- fluidPage(
    shinyjs::useShinyjs(),
    theme = shinytheme("united"),
    tags$head(
        tags$style(
            HTML(".shiny-notification {
                             position:fixed;
                             top: calc(50%);
                             left: calc(50%);
                             font-family:Verdana;
                             fontSize:xx-large;
                             }
                             "
            )
        )
    ),
    
    # Application title
    fluidRow(
        column(width = 3,
               img(src="ParthaInPetra.jpg", width=200, height=112)
        ),
        column(width = 6,
               h1("RenegeMuni", style="color:blue; text-align: center;"),
               h3("Renege Predictor", style="color:darkred; text-align: center;")
        ),
        column(width = 3,
               h4("...", style="color:blue; text-align: right;"),
               h4("Developed by: Partha Majumdar", style="color:blue; text-align: right;"),
               h5("Riyadh (Saudi Arabia), 30-May-2020", style="color:black; text-align: right;")
        )
    ),
    
    # Sidebar to accept Input 
    fluidRow(
        column(7,
               fluidRow(
                   column(12,
                          h3("Enter the Parameters below and click SUBMIT", 
                             style="color:blue; text-align: center;")
                          )
               ),
               fluidRow(
                   column(6,
                          wellPanel(
                              selectInput(inputId = "v_doj_extended", 
                                          label = "Whether Date of Joining Extended",
                                          multiple = FALSE,
                                          c("Yes" = "1",
                                            "No" = "2"
                                          )
                              ),
                              numericInput(inputId = "v_duration_to_accept_offer", 
                                           label = "Duration to accept offer (in days)", 
                                           value = 10, min = 0, max = 30, step = 5
                              ),
                              numericInput(inputId = "v_notice_period", 
                                           label = "Notice Period (in days)", 
                                           value = 30, min = 0, max = 200, step = 10
                              ),
                              numericInput(inputId = "v_percent_hike_expected", 
                                           label = "Hike Expected (in percentage)", 
                                           value = 30, min = 0, max = 100, step = 5
                              ),
                              numericInput(inputId = "v_percent_hike_offered", 
                                           label = "Hike Offered (in percentage)", 
                                           value = 30, min = 0, max = 100, step = 5
                              ),
                              numericInput(inputId = "v_percent_difference_ctc", 
                                           label = "Difference in CTC (in percentage)", 
                                           value = 30, min = 0, max = 100, step = 5
                              )
                          )
                   ),
                   column(6,
                          wellPanel(
                              selectInput(inputId = "v_joining_bonus", 
                                          label = "Whether Joining Bonus was given",
                                          multiple = FALSE,
                                          c("Yes" = "1",
                                            "No" = "2"
                                          )
                              ),
                              selectInput(inputId = "v_relocation_status", 
                                          label = "Whether Relocated",
                                          multiple = FALSE,
                                          c("Yes" = "1",
                                            "No" = "2"
                                          )
                              ),
                              selectInput(inputId = "v_gender", 
                                          label = "Gender",
                                          multiple = FALSE,
                                          c("Male" = "1",
                                            "Female" = "2"
                                          )
                              ),
                              selectInput(inputId = "v_source", 
                                          label = "Source",
                                          multiple = FALSE,
                                          c("Agency" = "1",
                                            "Direct" = "2",
                                            "Employee Referral" = "3"
                                          )
                              ),
                              numericInput(inputId = "v_relevant_experience", 
                                           label = "Relevant Experience (in years)", 
                                           value = 10, min = 0, max = 50, step = 1
                              ),
                              numericInput(inputId = "v_age", 
                                           label = "Age (in years)", 
                                           value = 25, min = 20, max = 60, step = 1
                              )
                          )
                   )
               ),
               fluidRow(
                   column(12,
                          wellPanel(
                              actionButton("submit", "Submit")
                          )
                   )
               )
        ),
        column(5,
               fluidRow(
                   column(12,
                          h1("Prediction", style="color:blue; text-align: center;"),
                          h4("Algorithm: Random Forest", style="color:blue; text-align: center;"),
                          div(id = "WillJoin", style="display:flex; align-items:center; justify-content:center;",
                              img(src="WillJoin.jpeg", width=600, height=400)
                            ),
                          div(id = "WillNotJoin", style="display:flex; align-items:center; justify-content:center;",
                              img(src="WillNotJoin.jpeg", width=600, height=400)
                            ),
                          h4(textOutput("predictionRandomForest"), style="color:white; text-align: center;")
                   )
               )
        )
    )
)

# Define server logic required to draw a histogram
server <- function(input, output) {
    
    predictRenege <- eventReactive(input$submit,{
                                    shinyjs::hide("WillNotJoin")
                                    shinyjs::hide("WillJoin")
                                    
                                    # Check if Model for Random Forest Exists.
                                    # If exists, use Model.
                                    # Else, create Model
                                    if(file.exists("./ModelRandomForest.RData")) {
                                        load("./ModelRandomForest.RData")
                                    } else {
                                        withProgress(message = 'Generating Model...',
                                                     detail = 'This may take a while...', value = 100, {
                                                         v_rf_model <- createRandomForestModel()
                                                     })
                                    }
        
                                    v_rf_prediction <- predictUsingRandomForestModel(v_rf_model)

                                    return(v_rf_prediction)
                                },
                                ignoreNULL = FALSE
                            )

    createRandomForestModel <- function() {
        v_model_data <- readData()

        v_model_data[-13] <- lapply(v_model_data[-13], function(x) as.numeric(x))
        v_model_data$Status <- as.character(v_model_data$Status)
        v_model_data$Status <- as.factor(v_model_data$Status)
        # cat(paste("Point 2: ***", str(v_model_data), "+++\n", sep = ''), file = stderr())
        
        v_rf_model <- randomForest(
                                    Status ~ ., 
                                    data = v_model_data, 
                                    ntree = 1000, 
                                    mtry = 2, 
                                    importance = TRUE
                                    )
        save(v_rf_model, file = "./ModelRandomForest.RData")
        
        return(v_rf_model)
    }
    
    predictUsingRandomForestModel <- function(v_model) {
        v_data <- prepareData()
        v_prediction <- predict(v_model, v_data, type = "class")
        # cat(paste("Point 1: ***", v_prediction, "+++\n", sep = ''), file = stderr())
        
        return(v_prediction)
    }
    
    prepareData <- function() {
        v_data <- data.frame(
            DOJ_Extended = c(as.integer(input$v_doj_extended)),
            Duration_to_Accept_Offer = c(as.integer(input$v_duration_to_accept_offer)),
            Notice_Period = c(as.integer(input$v_notice_period)),
            Percent_Hike_Expected = c(as.integer(input$v_percent_hike_expected)),
            Percent_Hike_Offered = c(as.integer(input$v_percent_hike_offered)),
            Percent_Difference_CTC = c(as.integer(input$v_percent_difference_ctc)),
            Joining_Bonus = c(as.integer(input$v_joining_bonus)),
            Relocation_Status = c(as.integer(input$v_relocation_status)),
            Gender = c(as.integer(input$v_gender)),
            Source = c(as.integer(input$v_source)),
            Relevant_Experience = c(as.integer(input$v_relevant_experience)),
            Age = c(as.integer(input$v_age))
        )
        
        return(v_data)
    }
    
    readData <- function() {
        v_raw_data <- read.csv(file = "./Data/EmployeeJoining.csv", 
                               header = TRUE, sep = ",", quote = "", strip.white = TRUE)
        v_raw_data <- na.omit(v_raw_data)
        attach(v_raw_data)
        
        # Recode Data
        v_raw_data$DOJ_Extended[ which(DOJ_Extended == 0) ] <- 2
        
        v_raw_data$Joining_Bonus <- as.character(v_raw_data$Joining_Bonus)
        v_raw_data$Joining_Bonus[ which(Joining_Bonus == 'Yes') ] <- 1
        v_raw_data$Joining_Bonus[ which(Joining_Bonus == 'No') ] <- 2
        
        v_raw_data$Relocation_Status <- as.character(v_raw_data$Relocation_Status)
        v_raw_data$Relocation_Status[ which(Relocation_Status == 'Yes') ] <- 1
        v_raw_data$Relocation_Status[ which(Relocation_Status == 'No') ] <- 2
        
        v_raw_data$Gender <- as.character(v_raw_data$Gender)
        v_raw_data$Gender[ which(Gender == 'Male') ] <- 1
        v_raw_data$Gender[ which(Gender == 'Female') ] <- 2
        
        v_raw_data$Source <- as.character(v_raw_data$Source)
        v_raw_data$Source[ which(Source == 'Agency') ] <- 1
        v_raw_data$Source[ which(Source == 'Direct') ] <- 2
        v_raw_data$Source[ which(Source == 'Employee Referral') ] <- 3
        
        v_raw_data$Status <- as.character(v_raw_data$Status)
        v_raw_data$Status[ which(Status == 'Joined') ] <- 1
        v_raw_data$Status[ which(Status == 'Not Joined') ] <- 2
        
        # Extract Data for creating Model
        v_data_for_model <- subset(v_raw_data, 
                                   select = -c(Candidate_Ref, Offered_Band, LOB, Location)
        )
        
        return(v_data_for_model)
    }
    
    output$predictionRandomForest <- renderText({
        if(predictRenege() == 1) {
            shinyjs::hide("WillNotJoin")
            shinyjs::show("WillJoin")
        } else {
            shinyjs::hide("WillJoin")
            shinyjs::show("WillNotJoin")
        }
        
        v_rf_pred <- (ifelse(predictRenege() == 1, 'Will Join', 'Will not Join'))
        return(v_rf_pred)
    })
}

# Run the application 
shinyApp(ui = ui, server = server)
## 
## Listening on http://127.0.0.1:5366
## Warning in file(file, "rt"): cannot open file './Data/EmployeeJoining.csv': No
## such file or directory
## Warning: Error in file: cannot open the connection