# Module UI
  
#' @title   mod_calcmetas_ui and mod_calcmetas_server
#' @description  A shiny Module.
#'
#' @param id shiny id
#' @param input internal
#' @param output internal
#' @param session internal
#'
#' @rdname mod_calcmetas
#'
#' @keywords internal
#' @export 
#' @importFrom shiny NS tagList 
mod_calcmetas_ui <- function(id){
  ns <- NS(id)
  ui <- uiOutput(ns('metas'))
}
    
# Module Server
    
#' @rdname mod_calcmetas
#' @export
#' @keywords internal
    

mod_calcmetas_server <- function(input, output, session,  banco, get_data, configuracoes){
  ns <- session$ns
  # source('lapiInputs.R')
  
  to_export <- reactiveValues()
  
  get_ropse <- reactive({
    
    indicador <- 'RESULTADO OPERAÇÃO PECUÁRIA (R$/HA) SE'
    
    ref_var <- banco$prospectiva$engorda %>% filter(INDICADOR == indicador) %>% arrange(safra) %>% tail(1)
    
    banco$ind_top %>% filter(INDICADOR == indicador) -> config_var
    
    domain <- ref_var %>% select(min, q25, q50, q75, max) %>% unlist %>% as.vector
    referencia <- ref_var$ref
    bt_value <- 1
    valor_fazenda <- banco$fazenda %>% filter(INDICADOR == indicador)  %>% arrange(safra) %>% tail(1) %>% pull(VALOR)
    
    if(config_var$TOP == 'MENOR') {
      
      bt_value <- 0
      domain <- rev(domain)
      
    }
    
    list(
      label = "RESULTADO", 
      unidade = "R$/ha",
      value = valor_fazenda, 
      domain = domain, 
      entity = list(id = "fazenda", label = "Fazenda", value = valor_fazenda),
      reference = list(id = 'reference', label = "Referência", value = referencia),
      bt = bt_value, 
      casas = config_var %>% pull(casas)
    )
    
  })
  
  get_desembolso <- reactive({
    
    indicador <- 'DESEMBOLSO CAB/MÊS'
    
    ref_var <- banco$prospectiva$engorda %>% filter(INDICADOR == indicador)  %>% arrange(safra) %>% tail(1)
    
    banco$ind_top %>% filter(INDICADOR == indicador) -> config_var
    
    domain <- ref_var %>% select(min, q25, q50, q75, max) %>% unlist %>% as.vector
    referencia <- ref_var$ref
    bt_value <- 1
    valor_fazenda <- banco$fazenda %>% filter(INDICADOR == indicador) %>% arrange(safra) %>% tail(1) %>% pull(VALOR)
    
    if(config_var$TOP == 'MENOR') {
      
      bt_value <- 0
      domain <- rev(domain)
      
    }
    
    list(
      label = "Desembolso",
      unidade = "R$/cab/mês",
      value = valor_fazenda, 
      domain = domain, 
      entity = list(id = "fazenda", label = "Fazenda", value = valor_fazenda),
      reference = list(id = 'reference', label = "Referência", value = referencia),
      bt = bt_value, 
      casas = config_var %>% pull(casas)
    ) 
    
    
  })
  
  get_gmd <- reactive({
    
    indicador <- 'GMD GLOBAL (Kg)'
    
    ref_var <- banco$prospectiva$engorda %>% filter(INDICADOR == indicador) %>% arrange(safra) %>% tail(1)
    
    banco$ind_top %>% filter(INDICADOR == indicador) -> config_var
    
    domain <- ref_var %>% select(min, q25, q50, q75, max) %>% unlist %>% as.vector
    referencia <- ref_var$ref
    bt_value <- 1
    valor_fazenda <- banco$fazenda %>% filter(INDICADOR == indicador) %>% arrange(safra) %>% tail(1) %>% pull(VALOR)
    
    if(config_var$TOP == 'MENOR') {
      
      bt_value <- 0
      domain <- rev(domain)
      
    }
    
    list(
      unidade = 'kg/dia',
      label = "GMD", 
      value = valor_fazenda, 
      domain = domain, 
      entity = list(id = "fazenda", label = "Fazenda", value = valor_fazenda),
      reference = list(id = 'reference', label = "Referência", value = referencia),
      bt = bt_value, 
      casas = config_var %>% pull(casas)
    )
    
  })
  
  get_venda <- reactive({
    
    indicador <- 'VALOR MÉDIO DE VENDA'
    
    ref_var <- banco$prospectiva$engorda %>% filter(INDICADOR == indicador)  %>% arrange(safra) %>% tail(1)
    
    banco$ind_top %>% filter(INDICADOR == indicador) -> config_var
    
    domain <- ref_var %>% select(min, q25, q50, q75, max) %>% unlist %>% as.vector
    referencia <- ref_var$ref
    bt_value <- 1
    valor_fazenda <- banco$fazenda %>% filter(INDICADOR == indicador)  %>% arrange(safra) %>% tail(1) %>% pull(VALOR)
    
    if(config_var$TOP == 'MENOR') {
      
      bt_value <- 0
      domain <- rev(domain)
      
    }
    
    list(
      label = "VMV", 
      unidade = "R$/@",
      value = valor_fazenda, 
      domain = domain, 
      entity = list(id = "fazenda", label = "Fazenda", value = valor_fazenda),
      reference = list(id = 'reference', label = "Referência", value = referencia),
      bt = bt_value, 
      casas = config_var %>% pull(casas)
    ) 
    
  })

  output$metas <- renderUI({
    
    get_data$criar_bd_referencia()
    
    if(!is.null(banco$prospectiva$engorda)){
      
      
      last_safra <- banco$prospectiva$engorda$safra %>% unique %>% na.omit %>% sort %>% last
      last_safra_f <- banco$fazenda$safra %>% unique %>% na.omit %>% sort %>% last
      
      variaveis <- c(
        'RESULTADO OPERAÇÃO PECUÁRIA (R$/HA) SE',
        'GMD GLOBAL (Kg)',
        'ÁREA TOTAL FAZENDA',
        'VALOR MÉDIO DE VENDA',
        'DESEMBOLSO CAB/MÊS'
      )
      
      complete_farm <- function(fazenda, ref) {
        setdiff(names(ref), names(fazenda)) -> faltantes
        
        if(length(faltantes) > 0) {
          
          for(i in 1:length(faltantes)) {
            
            #i<-1
            faltantes_i <- faltantes[i]
            ref[[faltantes_i]]$media -> fazenda[[faltantes_i]]
            
          }
          
        }
        return(fazenda)
      }
      
      round_inttegra <- function(x, unidade, casas) {
        
        if(!is.na(unidade)) {
          if(unidade == '%') {
            x = x*100
          }  
        }
        
        if(is.na(casas)) {
          x
        } else {
          round(x, casas)
        }
      }
      
      ref_farm <- banco$fazenda %>% 
        left_join(
          banco$ind_top %>% 
            select(FRENTE, INDICADOR, casas, unidade),
          by = c("FRENTE", "INDICADOR")
        ) %>% 
        filter(safra == last_safra_f) %>% 
        filter(INDICADOR %in% variaveis) %>% 
        select(INDICADOR, VALOR, casas, unidade) %>% 
        rowwise %>%  
        mutate(VALOR = pmap_dbl(.l = list(VALOR, unidade, casas), .f = round_inttegra)) %>% 
        ungroup %>% 
        select(-casas, -unidade) %>% 
        spread(key = INDICADOR, value = VALOR) %>% 
        as.list
      
      ref_engorda <- banco$prospectiva$engorda %>% 
        left_join(
          banco$ind_top %>% 
            select(FRENTE, INDICADOR, casas),
          by = c("FRENTE", "INDICADOR")
        ) %>% 
        filter(safra == last_safra) %>% 
        filter(INDICADOR %in% variaveis) %>% 
        select(INDICADOR, media, top30 = ref, topind = q70, unidade, casas) %>% 
        rowwise %>%  
        mutate(media = pmap_dbl(.l = list(media, unidade, casas), .f = round_inttegra)) %>% 
        mutate(top30 = pmap_dbl(.l = list(top30, unidade, casas), .f = round_inttegra)) %>% 
        mutate(topind = pmap_dbl(.l = list(topind, unidade, casas), .f = round_inttegra)) %>% 
        ungroup %>% 
        select(-casas, -unidade) %>% 
        split(.$INDICADOR) %>% 
        lapply(., gather, key = 'chave', value = 'valor', -INDICADOR) %>% 
        lapply(select, - INDICADOR) %>% 
        lapply(spread, key = chave, value = valor) %>% 
        lapply(as.list)
      
      
      
      
      
      ref_farm <- complete_farm(ref_farm, ref_engorda)
      
      

      tags$div(fluidPage(
        fluidRow(
          tags$div(class="col-xs-12 col-sm-5 col-md-4 col-lg-4lapi-sidepanel",
                   lapiCollapsablePanel(id=ns("areaclp"), title="Parâmetros gerais",
                                        lapiNumericInput(ns('area_fazenda'), label='Área Produtiva', value = ref_farm$`ÁREA TOTAL FAZENDA`, caption="hectare"),
                                        lapiNumericInput(ns('peso_inicial'), label='Peso na entrada', value = 190, caption="kg de PV"),
                                        lapiNumericInput(ns('peso_saida'), label='Peso no abate', value = 530, caption="kg de PV"),
                                        lapiNumericInput(ns('rendimento'), label='Rendimento de carcaça',value = 54, min=0, max=100, 0,caption="%"),
                                        lapiNumericInput(ns('reposicao'), label='Reposição', value = 6.3, caption="R$/Kg")
                   ),
                   lapiCollapsablePanel(id="variaveiscolap", title="Parâmetros chave",
                                        lapiSliderInput(inputId = ns('resultado_esperado'), label="Resultado R$/ha/ano", 
                                                        min=get_ropse()$domain[1] %>% round(.,2), 
                                                        max=get_ropse()$domain[5] %>% round(.,2), 
                                                        step=.01, value=get_ropse()$value %>% round(.,2), 
                                                        marks=c(get_ropse()$reference$value %>% round(.,2)), 
                                                        marks_colors = c("blue"),
                                                        intervals=c(get_ropse()$domain %>% round(.,2)),
                                                        tooltip = write_ref_tooltip(
                                                          fazenda = ref_farm$`RESULTADO OPERAÇÃO PECUÁRIA (R$/HA) SE`, 
                                                          media = ref_engorda$`RESULTADO OPERAÇÃO PECUÁRIA (R$/HA) SE`$media, 
                                                          top30 = ref_engorda$`RESULTADO OPERAÇÃO PECUÁRIA (R$/HA) SE`$top30, 
                                                          topind = ref_engorda$`RESULTADO OPERAÇÃO PECUÁRIA (R$/HA) SE`$topind
                                                        )
                                        ),
                                        lapiSliderInput(inputId = ns('gmd_global'), 
                                                        label="GMD Global kg/d", 
                                                        min=get_gmd()$domain[1]%>% round(.,2), max=get_gmd()$domain[5]%>% round(.,2), 
                                                        step=.05, value=get_gmd()$value%>% round(.,2), marks=c(get_gmd()$reference$value%>% round(.,2)), 
                                                        marks_colors = c("blue"),
                                                        intervals=c(get_gmd()$domain%>% round(.,2)),
                                                        tooltip = write_ref_tooltip(
                                                          fazenda = ref_farm$`GMD GLOBAL (Kg)`, 
                                                          media = ref_engorda$`GMD GLOBAL (Kg)`$media, 
                                                          top30 = ref_engorda$`GMD GLOBAL (Kg)`$top30, 
                                                          topind = ref_engorda$`GMD GLOBAL (Kg)`$topind
                                                        )
                                        ),
                                        lapiSliderInput(inputId = ns('vmv'), 
                                                        label="Valor de venda R$/@", 
                                                        min=get_venda()$domain[1]%>% round(.,2), max=get_venda()$domain[5]%>% round(.,2), 
                                                        step=.5, value=get_venda()$value%>% round(.,2), marks=c(get_venda()$reference$value%>% round(.,2)), 
                                                        marks_colors = c("blue"),
                                                        intervals=c(get_venda()$domain%>% round(.,2)),
                                                        tooltip = write_ref_tooltip(
                                                          fazenda = ref_farm$`VALOR MÉDIO DE VENDA`, 
                                                          media = ref_engorda$`VALOR MÉDIO DE VENDA`$media, 
                                                          top30 = ref_engorda$`VALOR MÉDIO DE VENDA`$top30, 
                                                          topind = ref_engorda$`VALOR MÉDIO DE VENDA`$topind
                                                        )
                                        ),
                                        lapiSliderInput(inputId = ns('desembolso_fixo'), 
                                                        label="Desembolso R$/cab/mês", 
                                                        min=get_desembolso()$domain[1]%>% round(.,2), max=get_desembolso()$domain[5]%>% round(.,2), 
                                                        step=.5, value=get_desembolso()$value%>% round(.,2), 
                                                        marks=c(get_desembolso()$reference$value%>% round(.,2),get_desembolso()$reference$value%>% round(.,2)), 
                                                        marks_colors = c("blue","orange"),
                                                        intervals=c(get_desembolso()$domain%>% round(.,2)),
                                                        grt_is_better = F,
                                                        tooltip = write_ref_tooltip(
                                                          fazenda = ref_farm$`DESEMBOLSO CAB/MÊS`, 
                                                          media = ref_engorda$`DESEMBOLSO CAB/MÊS`$media, 
                                                          top30 = ref_engorda$`DESEMBOLSO CAB/MÊS`$top30, 
                                                          topind = ref_engorda$`DESEMBOLSO CAB/MÊS`$topind
                                                        )
                                        )
                   )
                   
          ),
          tags$div(class="col-xs-12 col-sm-7 col-md-8 col-lg-8 lapi-mainpanel",
                   tags$div(
                     tags$h4("TABELA DE RESULTADOS", class="lapi-tabletitle", style = 'float:left;'), 
                     downloadButton(ns("downloadData"),label = "Excel", style = 'float:right; padding-bottom:4px; padding-top:4px;')
                   ),
                   uiOutput(ns('metas_engorda'))
          )
        )
      )
      )
    }
    
    
  })
  
  output$downloadData <- downloadHandler(
    filename = function() {
      paste0('metas_engorda_',Sys.Date(), ".xlsx", sep = "")
    },
    content = function(file) {
      openxlsx::write.xlsx(to_export$engorda_excel %>% as.data.frame %>% select(1,3,2), file = file)
    }
  )
  
  observeEvent(input$gmd_global, {
    
    pred <- get_desembolso()$reference$value %>% round(.,2)
    
    if(!is.null(banco$mod_gmd_des)){
      tryCatch({
        predict(banco$mod_gmd_des, newdata = tibble(safra ='2018/2019', gmd = input$gmd_global)) %>% as.numeric %>% round(.,2) -> pred  
      }, error = function(e){
        
      })
      
    }
    
    updateLapiSliderInput(session, inputId = "desembolso_fixo", marks=c(get_desembolso()$reference$value%>% round(.,2), pred))
    
  })
  
  calc <- reactive({
    
    tibble(
      area = input$area_fazenda,
      resultado = input$resultado_esperado,
      gmd = input$gmd_global,
      peso_entrada = input$peso_inicial,
      peso_abate = input$peso_saida,
      rendimento = input$rendimento,
      valor_medio_de_venda = input$vmv,
      reposicao = input$reposicao,
      desembolso = input$desembolso_fixo
    )%>%
    calc_engorda 
  })
  
  baseTibble <- tibble(id = c(
    "resultado_total",
    "ganho_total",
    "peso_arroba",
    "ganho_total_arroba",
    "valor_venda_cabeca",
    "reposicao_cabeca",
    "tempo",
    "taxa_de_abate",
    "desembolso_boi",
    "desembolso_arroba",
    "resultado_boi",
    "bois_a_abater",
    "rebanho_medio",
    "lotacao_cab",
    "lotacao_ua",
    "resultado_arroba",
    "lucratividade_arroba",
    "desembolso_vmv",
    "faturamento_total",
    "desembolso_anual",
    "desembolso_reposicao"
  ),parametro = c(
    "Resultado Total",
    "Ganho total em PV",
    "Peso ao abate em @",
    "Ganho total em @",
    "Valor de venda cab.",
    "Valor reposição ",
    "Tempo de permanência",
    "Taxa de abate",
    "Desembolso/boi",
    "Desembolso/@ produzida",
    "Resultado/boi",
    "Bois para abater",
    "Rebanho Médio",
    "Lotação em Cabeças",
    "Lotação em UA's",
    "Resultado/@ produzida",
    "Lucratividade/@ produzida",
    "Desembolso/valor de venda",
    "Faturamento total",
    "Desembolso operacional anual",
    "Desembolso reposição total "
  ),unidade = c(
    "R$/ano",
    "kg de PV",
    "@/cab",
    "@/cab",
    "R$/cab",
    "R$/cab",
    "meses",
    "%",
    "R$",
    "R$/@",
    "R$/cab",
    "Cabeças",
    "Cabeças",
    "cab/ha",
    "UA/ha",
    "R$",
    "%",
    "%",
    "R$",
    "R$",
    "R$"
  ))
  
  output$metas_engorda <- function(){ #renderTable({
      
      calc() %>% select(-area, -resultado, -gmd, -peso_entrada, -peso_abate, -rendimento, -valor_medio_de_venda,
                        -reposicao, -desembolso) %>%
        mutate(
          bois_a_abater = floor(bois_a_abater),
          peso_arroba = format(round(peso_arroba, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          desembolso_anual = format(round(desembolso_anual, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          desembolso_arroba = format(round(desembolso_arroba, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          desembolso_boi = format(round(desembolso_boi, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          desembolso_reposicao = format(round(desembolso_reposicao, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          desembolso_vmv = format(round(desembolso_vmv*100, digits=1), nsmall = 1, decimal.mark = ',', big.mark = '.'),
          faturamento_total = format(round(faturamento_total, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          ganho_total = format(round(ganho_total, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          ganho_total_arroba = format(round(ganho_total_arroba, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          lotacao_cab = format(lotacao_cab, digits=2L, nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          lotacao_ua = format(lotacao_ua, digits=2L, nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          lucratividade_arroba = format(round(lucratividade_arroba*100, digits=1), nsmall = 1, decimal.mark = ',', big.mark = '.'),
          producao_a_ha = format(round(producao_a_ha, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          rebanho_medio = format(round(rebanho_medio, digits=0), nsmall = 0, decimal.mark = ',', big.mark = '.'),
          reposicao_cabeca = format(round(reposicao_cabeca, digits = 2), digits=2L, nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          resultado_arroba = format(round(resultado_arroba, digits=2), nsmall = 2, decimal.mark = ',', big.mark = '.'),
          resultado_boi = format(round(resultado_boi, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          resultado_total = format(round(resultado_total, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          valor_venda_cabeca = format(valor_venda_cabeca, digits=2L, nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          taxa_de_abate = format(round(taxa_de_abate*100, digits = 2), digits=2L, nsmall = 2L, decimal.mark = ',', big.mark = '.'),
          tempo = format(round(tempo, digits = 2), digits=2L, nsmall = 2L, decimal.mark = ',', big.mark = '.')
        ) -> aux
    
      
      tibble(variavel=names(aux), valor=as.character(aux[1,])) -> aux
      
      tibble(
        'Área Produtiva' = format(round(input$area_fazenda, digits=0), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
        'Resultado' = format(round(input$resultado_esperado, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
        'GMD global' = format(round(input$gmd_global, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
        'Peso entrada' = format(round(input$peso_inicial, digits=0), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
        'Peso no abate' = format(round(input$peso_saida, digits=0), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
        'Rendimento de carcaça' = format(round(input$rendimento, digits=1), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
        'Valor de venda' = format(round(input$vmv, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
        'Reposição' = format(round(input$reposicao, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.'),
        'Desembolso' = format(round(input$desembolso_fixo, digits=2L), nsmall = 2L, decimal.mark = ',', big.mark = '.')
      ) %>%
        pivot_longer(everything(), names_to = 'Parâmetro', values_to = 'Valor') %>% 
        mutate(Valor = as.character(Valor)) %>% 
        bind_cols(
          tibble(
            Unidade = c(
              "ha",'R$/ha/ano',"kg/d","kg","kg",'%',"R$/@","R$/kg","R$/cab/mês"
            )
          )
        ) %>%
        bind_rows(
          baseTibble %>% 
            inner_join(aux, by=c("id"="variavel")) %>% 
            select("Parâmetro" = parametro, Unidade = unidade, Valor = valor)
        ) -> to_export$engorda_excel
         
        
      
      baseTibble %>% inner_join(aux, by=c("id"="variavel")) %>%
        mutate(parametro = cell_spec(parametro, format = "html", popover = spec_popover(
          content = "Explicação da variável",
          title = NULL,                           # title will add a Title Panel on top
          position = 'top'
        ))
        ) %>%
        select("Parâmetro"="parametro", "Unidade"="unidade", "Valor"="valor") %>%
      knitr::kable(escape = F, format = 'html') %>% 
        kable_styling(bootstrap_options = c("bordered","condensed","striped", "hover")) %>% 
        column_spec(1, bold=T, color = "black") %>% row_spec(0, bold=T, background="#c4c4c4")
  }
  
}
    
## To be copied in the UI
# mod_calcmetas_ui("calcmetas_ui_1")
    
## To be copied in the server
# callModule(mod_calcmetas_server, "calcmetas_ui_1")
 
