library(shiny)
library(readr)
library(tidyr)
library(dplyr)
library(purrr)
library(shinyBS)
library(magrittr)
library(shinyjs)
library(shinyBS)
library(httr)
library(jsonlite)
library(readxl)
library(knitr)
library(kableExtra)
library(openxlsx)
source("descritiva.R")
source("log.R")
options(scipen = 8)

logwriter = get_log_writer('regua')

# options(shiny.reactlog=TRUE)

go_login <- function(redirect_url, session){
  
  if(session$clientData$url_port != "") {
    port <- paste0(":", session$clientData$url_port)
  } else {
    port <- ""
  }
  
  redirect_url <- paste0(session$clientData$url_protocol, "//", session$clientData$url_hostname, port, session$clientData$url_pathname)
  
  runjs(
    paste0('window.location.replace("https://inttegra.com/sistema/sistema.htm?l=login&redirect_uri=',redirect_url,'");')
  )  
}

get_url <- function(url,token){
  # set_config(config(ssl_verifypeer = 0L))
  return(content(GET(url = url,add_headers(Authorization =  paste0("Bearer ",token))),as = 'text'))
}

get_user <- function(token){
  get_url(url='https://www.inttegra.com/api/usuario',token=token)
}

AuthCode <- function(session){
  pars <- parseQueryString(session$clientData$url_search)
  if(length(pars$token) > 0){
    return(pars$token)
  }
}

shinyServer(function(input, output,session) {
  
  acesso<-reactiveValues()
  acesso[['permissao']] <- T#Sys.getenv("APPS_INTTEGRA_DEVELOPMENT") != ""
  logon_info<-reactiveValues()
  
  shiny::onSessionEnded(function(){
    tout <- get_date_time()
    
    if(isolate(acesso[['permissao']]) == T && !is.null(isolate(logon_info[['usuario']])) ){
      
      write.table(isolate({
        list(
          franquia = ifelse(is.null(logon_info$usuario$franquia), "", logon_info$usuario$franquia), 
          id_franquia = ifelse(is.null(logon_info$usuario$id_franquia), "", logon_info$usuario$id_franquia), 
          email = ifelse(is.null(logon_info$usuario$email),"",logon_info$usuario$email),
          logindate = logon_info$login$data, logintime = logon_info$login$hora,
          logoutdate = tout$data, logouttime = tout$hora
        )
      }), file=paste0("log/regua",format(Sys.Date(), "%Y"),".csv"), append = T, col.names = F, row.names=F, sep=";")
      
    }
  })
  
  observeEvent(session,{
    AuthCode(session)->token
    if(!acesso$permissao){
      if(is.null(token)){
        go_login("regua", session)
      } else {
        
        tryCatch({
          # usuario<-fromJSON(get_user(token))
          usuario<-fromJSON(system(paste('curl -k -H "Authorization: bearer', token,'" https://www.inttegra.com/api/usuario'),intern=T))
        },error=function(e){
          runjs(paste("alert('","Erro ao buscar dados do usuário. Contacte o desenvolvedor.","')"))
          stopApp()
        })
        
        if(!is.null(usuario$nome)){
          acesso[['permissao']]<-T
          logon_info[['usuario']]<-usuario
          logon_info[['login']] <- get_date_time()
        }
      }
    } else {
      logon_info[['usuario']]<-list(id_franquia="622",nome='Luigi', franquia="TERRA")
      logon_info[['login']] <- get_date_time()
    }
    
  })
  
  options(shiny.sanitize.errors = T)
  
  output$usuario <- renderPrint({logon_info$usuario})
  
  output$tela_geral<-renderUI({
    if(acesso$permissao){
      
      tagList(
        titlePanel("Calculadora de réguas"),
        sidebarLayout(
          uiOutput("sidebar"),
          uiOutput("mainpanel")
        )  
      )
    } else {
      tagList(
        # h1(as.character(usuario$nome)),
        # uiOutput("senha_ui")  
      )
    }
  })
  
  
  ### Carregamento de bancos --------------------------------------------
  banco<-reactiveValues()
  
  load("bd/banco.rData")
  
  load("bd/sistemaChoices.rData")
  
  dados %<>% dplyr::left_join(sistemaChoices, by=c("obs_id"))
  
  
  banco[['bd']] <- dados %>% 
    rename(sistema=`SISTEMA PECUÁRIA`
           ,safra=SAFRA
           ,franqueado=FRANQUEADO
           ,estado=ESTADO
           ,nome=`NOME DA FAZENDA`
           ,pastoconf=`PASTO/CONFINAMENTO`
           ,agricultura=`AGRICULTURA PROPRIA  (COM/SEM)`
    ) %>% 
    mutate(VALOR = as.numeric(VALOR)) %>% 
    left_join(
      read_xlsx(
        'bd/franqueados.xlsx',1
      )
    ) %>% mutate(sistema = gsub(pattern = 'CRE, COM COMPRAS', replacement = 'CRIA-RECRIA-ENGORDA', sistema))
  
  banco[["ind_top"]] <- read_xlsx('bd/ind_top.xlsx', 1)
  
  banco[["correcao"]] <- read_xlsx('bd/correcao_anual.xlsx')
  
  
  ### Filtros --------------------------------------------------------------------------------
  
  output$sidebar<-renderUI({
    if(!is.null(logon_info$usuario)){
      sidebarPanel(width = "3",
                   h3("Filtros"),
                   selectInput("sistema","Sistema",choices=c("Todos",sort(unique(banco$bd$sistemaChoices))),selected = "Todos",multiple = T),
                   selectInput("safra","Safra",choices=c("Todas",sort(unique(banco$bd$safra))),selected = "Todas",multiple = T),
                   # if(is.null(logon_info$usuario$id_franquia)||as.numeric(logon_info$usuario$id_franquia)==622){
                   #   selectInput("franqueado","Franqueado",choices=c("Todos",sort(unique(banco$bd$franqueado))),selected = "Todos",multiple = T,selectize = T)  
                   # } else {
                   #   selectInput(
                   #     "franqueado","Franqueado"
                   #     ,choices=
                   #       c(
                   #         "Todos",
                   #          sort(unique(banco$bd %>% filter(as.numeric(id_franquia)==as.numeric(logon_info$usuario$id_franquia)) %>% pull(franqueado)))
                   #       )
                   #     ,selected = "Todos"
                   #     ,multiple = T
                   #     ,selectize = T
                   #   )  
                   # },
                   selectInput("estado","Estado/País",choices=c("Todos",sort(unique(banco$bd$estado))),selected = "Todos",multiple = T),
                   # if(is.null(logon_info$usuario$id_franquia)||as.numeric(logon_info$usuario$id_franquia)==622){
                   # selectInput("nome","Fazenda/Grupo",choices=c("Todos",sort(unique(banco$bd$nome))),selected = "Todos",multiple = T)
                   # },
                   selectInput("pastoconf","Com ou sem confinamento",choices=c("Todos",sort(unique(banco$bd$pastoconf))),selected = "Todos",multiple = T),
                   selectInput("agricultura","Agricultura",choices=c("Todos",sort(unique(banco$bd$agricultura))),selected = "Todos",multiple = T),
		               selectInput("intensificacao", "Intensificação", 
		                           choices = list("Todos" = 0, "Desembolso pecuário <= 10000" = 1, 
		                                          "Desembolso pecuário > 10000" = 2), selected = 0, multiple = F),
                   checkboxInput(inputId = 'corrigir', label = "Corrigir valores, IPCA", value = T),
                   actionButton("filtrar","Iniciar/Filtrar")
      )  
    }
  })
  
  observe({
    if ("Todos" %in% input$sistema) {
      if(which(input$sistema=="Todos")==1){
        if(length(input$sistema)>1){
          selected_choices<-setdiff(input$sistema,"Todos")  
        } else {
          selected_choices<-"Todos"  
        }
      } else {
        selected_choices<-"Todos"
      }
      updateSelectInput(session, "sistema", selected = selected_choices)
    }
  })
  
  observe({
    if ("Todos" %in% input$franqueado) {
      if(which(input$franqueado=="Todos")==1){
        if(length(input$franqueado)>1){
          selected_choices<-setdiff(input$franqueado,"Todos")  
        } else {
          selected_choices<-"Todos"  
        }
      } else {
        selected_choices<-"Todos"
      }
      updateSelectInput(session, "franqueado", selected = selected_choices)
    }
  })
  
  observe({
    if ("Todas" %in% input$safra) {
      if(which(input$safra=="Todas")==1){
        if(length(input$safra)>1){
          selected_choices<-setdiff(input$safra,"Todas")  
        } else {
          selected_choices<-"Todas"  
        }
      } else {
        selected_choices<-"Todas"
      }
      updateSelectInput(session, "safra", selected = selected_choices)
    }
  })
  
  observe({
    if ("Todos" %in% input$nome) {
      if(which(input$nome=="Todos")==1){
        if(length(input$nome)>1){
          selected_choices<-setdiff(input$nome,"Todos")  
        } else {
          selected_choices<-"Todos"  
        }
      } else {
        selected_choices<-"Todos"
      }
      updateSelectInput(session, "nome", selected = selected_choices)
    }
  })
  
  observe({
    if ("Todos" %in% input$estado) {
      if(which(input$estado=="Todos")==1){
        if(length(input$estado)>1){
          selected_choices<-setdiff(input$estado,"Todos")  
        } else {
          selected_choices<-"Todos"  
        }
      } else {
        selected_choices<-"Todos"
      }
      updateSelectInput(session, "estado", selected = selected_choices)
    }
  })
  
  observe({
    if ("Todos" %in% input$agricultura) {
      if(which(input$agricultura=="Todos")==1){
        if(length(input$agricultura)>1){
          selected_choices<-setdiff(input$agricultura,"Todos")  
        } else {
          selected_choices<-"Todos"  
        }
      } else {
        selected_choices<-"Todos"
      }
      updateSelectInput(session, "agricultura", selected = selected_choices)
    }
  })
  
  observe({
    if ("Todos" %in% input$pastoconf) {
      if(which(input$pastoconf=="Todos")==1){
        if(length(input$pastoconf)>1){
          selected_choices<-setdiff(input$pastoconf,"Todos")  
        } else {
          selected_choices<-"Todos"  
        }
      } else {
        selected_choices<-"Todos"
      }
      updateSelectInput(session, "pastoconf", selected = selected_choices)
    }
  })
  
  filtrar <- reactive({
    
    if(input$corrigir) {
      
      banco[['bd_filtrado']] <- banco$bd %>% 
        left_join(
          banco$ind_top %>% 
            select(INDICADOR, unidade), by = 'INDICADOR'
        ) %>% 
        left_join(
          banco$correcao %>% 
            select(safra = SAFRA, correcao = valor), by = 'safra'
        ) %>% 
        mutate(VALOR = ifelse(unidade != "R$" | is.na(unidade), VALOR, VALOR * correcao))
      
    } else {
      
      banco[['bd_filtrado']] <- banco$bd
      
    }
    
    if(input$sistema!="Todos"){
      banco$bd_filtrado<-banco$bd_filtrado %>% 
        filter(sistemaChoices %in% input$sistema) 
    } 
    
    if(input$safra!="Todas"){
      banco$bd_filtrado<-banco$bd_filtrado %>% 
        filter(safra %in% input$safra) 
    } 
    
    if(!is.null(input$franqueado)){
      if(input$franqueado!="Todos"){
        banco$bd_filtrado<-banco$bd_filtrado %>%
          filter(franqueado %in% input$franqueado)
      }  
    }
    
    
    if(input$estado!="Todos"){
      banco$bd_filtrado<-banco$bd_filtrado %>% 
        filter(estado %in% input$estado) 
    }
    
    if(!is.null(input$nome)){
      if(input$nome!="Todos"){
        banco$bd_filtrado<-banco$bd_filtrado %>%
          filter(nome %in% input$nome)
      }  
    }
    
    
    if(input$agricultura!="Todos"){
      banco$bd_filtrado<-banco$bd_filtrado %>% 
        filter(agricultura %in% input$agricultura) 
    }
    
    if(input$pastoconf!="Todos"){
      banco$bd_filtrado<-banco$bd_filtrado %>% 
        filter(pastoconf %in% input$pastoconf) 
    }
    # Issue #26 Adicionar filtro Intensificacao a aplicacao regua
    # implementacao yvescavalcanti
  
    if(input$intensificacao!=0){
      if(input$intensificacao == 1){
        f <- function(x)x<=10000
      }else{
        f <- function(x)x>10000
      }
      # selecionando código das fazendas que atendem ao critério do filtro
      fazendas <- banco$bd_filtrado %>% 
        filter(INDICADOR == "DESEMBOLSO PECUÁRIO POR HA/ANO (SEM COMPRA DE GADO)" & f(VALOR)) 
      fazendas <- unique(fazendas$obs_id)
      # selecionando linhas cujos código da fazenda pertencem à lista acima definida
      
      banco$bd_filtrado <- banco$bd_filtrado %>% 
        filter(obs_id %in% fazendas)
    }
  })
  
  observeEvent(input$filtrar,{
    filtrar()
  })
  
  
  
  ### Tabelas --------------------------------------------------------------
  calc_regua_reactive <- reactive({
    
    if(!is.null(banco$bd_filtrado)){
      
      banco$bd_filtrado %>% 
        filter(INDICADOR == "RESULTADO OPERAÇÃO PECUÁRIA (R$/HA) SE") %>% 
        mutate(
          top30 = quantile(VALOR,probs = c(.7)),
          ref = ifelse(VALOR > top30, 1, 0)
        ) %>% 
        dplyr::select(`TÉCNICO`, franqueado, safra, nome, MUNICÍPIO, top30, ref) -> ref
      
      
      banco$bd_filtrado %>% 
        mutate(INDICADOR == ifelse(INDICADOR == 'RESULTADO OP/HA  SOJA', 'RESULTADO OP/HA SOJA', INDICADOR)) %>%
        mutate(INDICADOR == ifelse(INDICADOR == 'CUSTO RAÇÃO TOTAL KG/DIA', 'CUSTO RAÇÃO TOTAL (R$/dia)', INDICADOR)) %>%
        mutate(INDICADOR == ifelse(INDICADOR == 'RESULTADO CAIXA POR HA', 'RESULTADO DE CAIXA (R$/HA)', INDICADOR)) %>%
        filter(FRENTE != "REPRODUÇÃO") %>% 
        bind_rows(
          banco$bd_filtrado %>% 
            filter(FRENTE == "REPRODUÇÃO") %>% 
            mutate(safra_ref = ifelse(FRENTE == "REPRODUÇÃO", stringr::str_extract(INDICADOR,"\\d\\d.\\d\\d"), NA)) %>% 
            mutate(ano1 = ifelse(!is.na(safra_ref), as.numeric(stringr::str_extract(safra_ref, "\\d\\d")), NA)) %>% 
            mutate(INDICADOR = ifelse(FRENTE == "REPRODUÇÃO", gsub("\\(SF([^\\)]+)\\)","", INDICADOR), INDICADOR)) %>% 
            mutate(INDICADOR = ifelse(FRENTE == "REPRODUÇÃO", gsub("SF(.*)","", INDICADOR), INDICADOR)) %>%
            mutate(INDICADOR = trimws(INDICADOR, which  = "both")) %>% 
            arrange(INDICADOR, ano1) %>% 
            group_by(INDICADOR) %>% 
            filter(ano1 == last(ano1) | is.na(ano1))
        ) %>% 
        left_join(
          ref
        ) %>% 
        right_join(
          banco$ind_top
        ) %>% 
        group_by(INDICADOR, FRENTE, TOP) %>% 
        nest %>% 
        mutate(regua = purrr::pmap(.l=list(data, top = TOP), .f = calc_regua)) %>% 
        unnest(regua) %>% 
        arrange(FRENTE, INDICADOR) %>% 
        mutate(
          "Piores 25%" = paste0(ini_simbol, q25),
          "25% a 50%" = ifelse(TOP == "MAIOR", paste0(q25, " - ", q50), paste0(q50, " - ", q25)),
          "50% a 75%" = ifelse(TOP == "MAIOR", paste0(q50, " - ", q75), paste0(q75, " - ", q50)),
          "Melhores 25%" = paste0(fim_simbol, q75)
        ) %>% 
        mutate(hpd = as.character(hpd)) %>% 
        mutate(hpd = ifelse(is.na(hpd), "Não determinado", hpd)) %>% 
        mutate(ref = as.character(ref)) %>% 
        mutate(ref = ifelse(FRENTE == "AGRICULTURA", "-", ref)) %>% 
        mutate(ref = ifelse(INDICADOR %in% c(
          "RESULTADO OP/HA AGRICULTURA SOJA\\MILHO\\OUTRAS",
          "RESULTADO OP/HA ARRENDAMENTO CANA",
          "RESULTADO OP/HA ARRENDAMENTO PASTO",
          "RESULTADO OP/HA ARRENDAMENTO SOJA\\MILHO",
          "RESULTADO OP/HA CANA",
          "RESULTADO OP/HA EUCALIPTO",
          "RESULTADO OP/HA SERINGUEIRA",
          "VALOR DO PARQUE POR HA PLANTADO",
          "FATURAMENTO AGRÍCOLA/FUNCIONÁRIOS",
          "TOTAL HA PLANTADOS/FUNCIONÁRIOS"
        ), "-", ref)) %>% 
        ungroup %>% 
        dplyr::select(FRENTE,INDICADOR,Unidade = unidade, `Piores 25%`, `25% a 50%`, `50% a 75%`, `Melhores 25%`,"TOP 30" = ref,"Potencial Técnico" = hpd) -> tabela
      
      return(tabela)
    }
  })
  
  output$regua_ui <- function(){
    
    # browser()
    calc_regua_reactive() %>% 
      kable() %>% 
      kable_styling(bootstrap_options = "striped", full_width = T) %>% 
      collapse_rows(columns = 1, valign = "top")
    
  }
  
  output$downloadRegua <- downloadHandler(
    
    filename = function() {
      paste("regua_", Sys.Date(), ".xlsx", sep="")
    },
    content = function(file) {
      write.xlsx(x=calc_regua_reactive() %>% as.data.frame,file = file)
    }
    
  )
  
  
  
  #### Tela MainPanel ------------------------------------------------------
  output$mainpanel<-renderUI({
    tagList(
      if(!is.null(banco$bd_filtrado)){
        mainPanel(
          tags$div(
            downloadLink("downloadRegua", "Download"),
            style = 'float:right;'
          ),
          tableOutput('regua_ui')
        )
      }
    )
  })
  
  
})


