library(shinydashboard)
library(RMySQL)
#library(sqldf)
library(feather)
library(ggplot2)
library(dplyr)
library(reshape2)
library(lubridate)
library(plotly) 

# 1. Data preprocessing ------------------------------------------------------

# web/file

loading <- "file" 

# 1.1. Load from web db ---------------------------------------------------

if (loading == "web"){
  # 1.1.1. Connect db
  db <-  dbConnect(MySQL(), user='analyst', password='exa_analyst1&',
                   dbname='esi_management',
                   host='lecanaldb.c12hbxfn3xzn.eu-west-1.rds.amazonaws.com',
                   port=3306)
  
  # 1.1.2. load one table
  db_table_load <- function(table){
    # read
    rs = dbSendQuery(db, paste0("select * from ", table))
    df = fetch(rs, n=-1)
    # cach
    write_feather(df, paste0("data/", table))
  }
  
  # 1.1.3. Load tables
  df_entity <- db_table_load("wp_esi_entity")
  df_tag <- db_table_load("wp_esi_tag")
  df_tag_entity <- db_table_load("wp_esi_tag_entity")
  df_investment <- db_table_load("wp_esi_investment")
  
  # 1.1.4. disconnect
  dbDisconnect(db)
}

# 1.1.5 packages management
detach("package:RMySQL", unload=TRUE)
library(sqldf)


# 2. Load from cached files --------------------------------------------------

if(loading == "file"){
  df_entity <- read_feather("data/wp_esi_entity")
  df_tag <- read_feather("data/wp_esi_tag")
  df_tag_entity <- read_feather("data/wp_esi_tag_entity")
  df_investment <- read_feather("data/wp_esi_investment")
}

# UI ----------------------------------------------------------------------

sidebar <- dashboardSidebar(
  sidebarMenu(
    menuItem("Entities", icon = icon("dashboard"),
             menuSubItem("By countries", tabName = "q1"),
             menuSubItem("By tags", tabName = "q3")
             ),
    menuItem("Investments", icon = icon("money"),
             menuSubItem("By tags", tabName = "q2")
             )
  )
)

body <- dashboardBody(
  tabItems(
    tabItem(tabName = "q1",
            fluidPage(
              fluidRow(h2("Distribution of AI companies by countries")),
              fluidRow(selectInput("q1_choice", "Number of companies", c("> 100", "10-100", "1-10"))),
              fluidRow(
                column(3, textInput("q1_entities_min", "Min", "1")),
                column(3, textInput("q1_entities_max", "Max", "5"))
              ),
              fluidRow(plotlyOutput("q1")),
              fluidRow(DT::dataTableOutput("q1_table")),
              fluidRow(downloadButton('btn_download_q1', 'Download'))
            )
            
    ),
    tabItem(tabName = "q2",
            h2("Investments per tags"),
            selectInput("q2_choice", "Total raised", 
                        c("> 1,000,000,000", 
                          "1,000,000  - 1,000,000,000", 
                          "< 1,000,000")),
            plotlyOutput("q2")
    ),
    tabItem(tabName = "q3",
            h2("Q3: What is the number of companies per tags?"),
            p("In progress ...")
    )
    
  )
)


ui <- dashboardPage(
  dashboardHeader(title = "ESI Analytics"),
  sidebar,
  body
)

# SERVER ------------------------------------------------------------------

server <- function(input, output) {
  
# Q1: Distribution of AI companies by countries --------------------------

  # 1. Range of companies from min to max 
  q1_get_min <- renderText({ input$q1_entities_min })
  
  q1_get_max <- renderText({ input$q1_entities_max })
  
  # 1. Data frame
  df_q1 <- reactive({
    df_entity %>% 
      group_by(country) %>% 
      summarise(sum = n()) %>% 
      arrange(-sum) %>% 
      mutate(country = ifelse(country=="", "N/A", country))  
  })
  
  # 2. Table
  output$q1_table <- DT::renderDataTable(
    DT::datatable(df_q1(),  options = list(pageLength = 10)) # , searching = FALSE
  )
  
  # 3. Graphs
  output$q1 <- renderPlotly({
    
    # 2. Select graphs
    
    # 2.1.  Countries with more than 100 companies
    gg_q1_1 <- df_q1() %>% 
      filter(sum > 100) %>% 
      ggplot(aes(reorder(country, sum), sum, fill=factor(sum))) +
      ggtitle("Countries with more than 100 companies") +
      ylab("Number of companies") +
      xlab("Countries") +
      geom_bar(stat="identity") +
      scale_fill_discrete(name = "Number") +
      coord_flip()
    
    # 2.2. Countries with 10-100 companies
    gg_q1_2 <- df_q1() %>% 
      filter(sum %in% 10:100) %>% 
      ggplot(aes(reorder(country, sum), sum, fill=factor(sum))) +
      ggtitle("Countries with 10-100 companies") +
      xlab("Countries") +
      ylab("Number of companies") +
      geom_bar(stat="identity") +
      scale_fill_discrete(name = "Number") +
      theme_bw() +
      coord_flip()
    
    # 2.3. Countries with 1-10 companies
    gg_q1_3 <- df_q1() %>% 
      filter(sum %in% 1:10) %>% 
      ggplot(aes(reorder(country, sum), sum, fill=factor(sum))) +
      ggtitle("Countries with 1-10 companies") +
      xlab("Countries") +
      ylab("Number of companies") +  
      geom_bar(stat="identity") +
      scale_fill_discrete(name = "Number") +
      coord_flip()
    
    # Select graph
    if(input$q1_choice == "> 100"){ g <- gg_q1_1 }
    if(input$q1_choice == "10-100"){ g <- gg_q1_2 }
    if(input$q1_choice == "1-10"){ g <- gg_q1_3 }
    
    
    gg_title <- paste0("Countries with ", q1_get_min(), " : ", q1_get_max(),  " companies")
    
    gg_q1 <- df_q1() %>% 
      filter(sum %in% q1_get_min():q1_get_max()) %>% 
      ggplot(aes(reorder(country, sum), sum, fill=factor(sum))) +
      ggtitle(gg_title) +
      xlab("Countries") +
      ylab("Number of companies") +  
      geom_bar(stat="identity") +
      scale_fill_discrete(name = "Number") +
      coord_flip()
    
        
    
    
    # Return result
    gg_q1
    
  })
  
  # Download
  output$btn_download_q1 <- downloadHandler(
    filename = "q1_entities_by_countries.csv",
    content = function(file) {
      write.csv(df_q1(), file)
    }
  )
    
# Q2: What's the investments per tags --------------------------
  
  output$q2 <- renderPlotly({
    
    # Q2.1. Join data
    s1 <- "select df_entity.*, df_tag_entity.* from df_entity left join df_tag_entity on df_entity.id=df_tag_entity.entity_id"
    s2 <- "select x.*, df_tag.* from x left join df_tag on x.tag_id = df_tag.id"
    x <- sqldf(s1)
    x <- sqldf(s2)
    
    # Q2.2. Change column names
    colnames(x) <- c("entity_id", "name", "description", "url", "is_investor", "country", 
                     "city", "entity_type_id", "founded_in", "employees", "acquired_by", 
                     "acquired_at", "acquired_amount", "total_raised", "latest_round_type", 
                     "facebook_link", "twitter_link", "linkedin_link", "status", "tag_id", 
                     "entity_id_1", "tag_id_1", "tag_name", "description_1", "parent_1")
    
    # Q2.3. Select features
    x <- x %>% 
      subset(select = c("entity_id", "total_raised", "tag_id")) %>% 
      filter(!is.na(tag_id))
    
    # Q2.4. Transform data set
    xt <- dcast(x, tag_id ~ total_raised)
    
    # Q2.5. Create tags column
    xt_tags <- xt %>% 
      subset(select = c("tag_id"))
    
    # Q2.6. For one tag function
    one_tag <- function(id){
      # 1. basic data set
      xt_case <- xt %>% 
        filter(tag_id == id) %>%
        subset(select=2:length(colnames(xt))) %>% 
        t()
      
      # 2. add "total_raised"
      rnames <- as.data.frame(row.names(xt_case))
      colnames(rnames) <- c("total_raised")
      
      xt_case <- cbind(rnames, xt_case)
      row.names(xt_case) <- NULL
      
      colnames(xt_case) <- c("total_raised", "sum_entities")
      
      xt_case <- xt_case %>% 
        mutate(total_raised = as.numeric(as.character(total_raised))) %>% 
        filter(!is.na(total_raised)) %>% 
        mutate(sum_total_raised = total_raised * sum_entities) %>% 
        subset(select = c("sum_total_raised"))
      
      return(xt_case)
    } # one_tag
    
    # Q2.7. init result data set
    z <- one_tag(unique(xt_tags$tag_id)[1])  
    colnames(z) <- c(unique(xt_tags$tag_id)[1])
    
    # 1. Progress object
    progress_q2 <- shiny::Progress$new()
    on.exit(progress_q2$close())
    progress_q2$set(message = "Processing", value = 0)
    
    # Q2.8. for loop
    end_for <- unique(xt_tags$tag_id)[2:length(unique(xt_tags$tag_id))]
    for(i in end_for){
      # Show progress
      progress_q2$inc(1/length(end_for), detail = paste("", i))
      
      tmp <- one_tag(i)
      colnames(tmp) <- c(i)
      z <- cbind(z, tmp)
    }
    
    # Q2.9. transpose
    z <- t(z)
    
    # Q2.10. sum total_raised
    xt_sum_total_raised <- as.data.frame(z) %>% 
      mutate(sum_total_raised = rowSums(.)) %>% 
      subset(select = c("sum_total_raised"))
    
    # Q2.11. Merge data sets
    xt_res <- cbind(xt_tags, xt_sum_total_raised)
    
    # Q2.12. Add tag names
    s <- "select xt_res.*, df_tag.* from xt_res left join df_tag on xt_res.tag_id = df_tag.id"
    df_res_final <- sqldf(s)
    
    df_res_final <- df_res_final %>% 
      subset(select = c("tag_id", "name", "sum_total_raised"))
    
    
    #
    # Q2.13. Draw graphs
    #
    
    # > 1,000,000,000
    gg_q2_1 <- df_res_final %>% 
      filter(sum_total_raised > 1000000000) %>% 
      ggplot(aes(reorder(name, sum_total_raised), sum_total_raised, fill=factor(sum_total_raised))) +
      ggtitle("Total raised of companies per Tag (> 1,000,000,000)") +
      xlab("Tags") +
      ylab("Total raised of company") +
      geom_bar(stat="identity") +
      scale_fill_discrete(name = "Number") +
      coord_flip()
    
    # > 1,000,000  1,000,000,000
    gg_q2_2 <- df_res_final %>% 
      filter((sum_total_raised > 1000000) &  (sum_total_raised < 1000000000)) %>% 
      ggplot(aes(reorder(name, sum_total_raised), sum_total_raised, fill=factor(sum_total_raised))) +
      ggtitle("Total raised of companies per Tag (1,000,000 - 1,000,000,000)") +
      xlab("Tags") +
      ylab("Total raised of company") +
      geom_bar(stat="identity") +
      scale_fill_discrete(name = "Number") +
      coord_flip()
    
    # < 1,000,000
    gg_q2_3 <- df_res_final %>% 
      filter(sum_total_raised <= 1000000) %>% 
      ggplot(aes(reorder(name, sum_total_raised), sum_total_raised, fill=factor(sum_total_raised))) +
      ggtitle("Total raised of companies per Tag (< 1,000,000)") +
      xlab("Tags") +
      ylab("Total raised of company") +
      geom_bar(stat="identity") +
      scale_fill_discrete(name = "Number") +
      coord_flip()
    
    # Select graph
    if(input$q2_choice == "> 1,000,000,000"){ g <- gg_q2_1 }
    if(input$q2_choice == "1,000,000  - 1,000,000,000"){ g <- gg_q2_2 }
    if(input$q2_choice == "< 1,000,000"){ g <- gg_q2_3 }
    
    # Return result
    g
    
  })
    
    
}



shinyApp(ui, server)