# Module UI
  
#' @title   mod_get_data_ui and mod_get_data_server
#' @description  A shiny Module.
#'
#' @param id shiny id
#' @param input internal
#' @param output internal
#' @param session internal
#'
#' @rdname mod_get_data
#'
#' @keywords internal
#' @export 
#' @importFrom shiny NS tagList 
mod_get_data_ui <- function(id){
  ns <- NS(id)
}
    
# Module Server
    
#' @rdname mod_get_data
#' @export
#' @keywords internal
    
mod_get_data_server <- function(input, output, session, banco, sel_one, historico, qperdeu, configuracoes){
  
  rules_warehouse <- function(){
    todas <- NULL
    engorda <- NULL
    ciclo_completo <- NULL
    y <- function(nome){
      if(nome == 'todas'){
        if(is.null(todas)){
          load("bd/reguaTodas.rData")
          todas <<- reguaTodas
        }
        return(todas)
      }
      if(nome == 'engorda'){
        if(is.null(engorda)){
          load("bd/reguaRecriaEngorda.rData")
          engorda <<- reguaRecriaEngorda
        }
        return(engorda)
      }
      if(nome == 'ciclo_completo'){
        if(is.null(ciclo_completo)){
          load("bd/reguaCriaRecriaEngorda.rData")
          ciclo_completo <<- reguaCompleto
        }
        return(ciclo_completo)
      }
      return(NULL)
    }
    return(y)
  }
  
  rules <- rules_warehouse()
  
  isolate({
    banco$prospectiva = list(engorda = rules('engorda'), ciclo_completo = rules('ciclo_completo'))
  })
  
  observeEvent(session, {

  # Status processamento ----------------------------------------------------
    banco[['processar']] <- 0
    
  # Carrega simulações de monte carlo ---------------------------------------
    load('bd/mc_completo.rData')
    banco[['mc']] <- mc_completo ## return
    

  # Carrega unidades para variaveis -----------------------------------------
    banco[['ind_top']] <- read_xlsx('bd/ind_top.xlsx') ## return
  

  # Carrega dados brutos ----------------------------------------------------

    load('bd/banco.rData')
    
    banco[['bd']] <- dados %>% ## return
      dplyr::rename(sistema = `SISTEMA PECUÁRIA`
                    ,safra = SAFRA
                    ,franqueado = FRANQUEADO
                    ,estado = ESTADO
                    ,nome = `NOME DA FAZENDA`
                    ,pastoconf = `PASTO/CONFINAMENTO`
                    ,agricultura = `AGRICULTURA PROPRIA  (COM/SEM)`
      ) %>%
      mutate(franqueado = if_else(franqueado == 1, 'TERRA', franqueado)) %>% 
      left_join(
        readxl::read_xlsx(
          'bd/franqueados.xlsx',1
        )
      )
    
    banco$bd %<>% 
      # mutate(VALOR = gsub("\\D+",  NA, VALOR)) %>% 
      mutate(VALOR =  as.numeric(VALOR)) 
    
    load('bd/clusters_all.rData')
    clusters_all -> banco[['clusters']] ## return
    
    banco$bd %<>% 
      left_join(
        banco$clusters %>% dplyr::select(sistema, safra = SAFRA, nome, clust), by = c('safra', 'nome', 'sistema')
      )
    
    banco$bd %>%
      select(nome, safra, franqueado,id_franquia) %>%
      distinct() %>%
      group_by(nome,franqueado,id_franquia) %>%
      summarise(n = n()) %>%
      ungroup %>%
      mutate(faz_id = 1:nrow(.)) -> banco[['faz_id_data']]  ## return

    banco$bd %<>%
      left_join(
        banco$faz_id_data %>% select(nome, franqueado, faz_id), by = c('nome', 'franqueado')
      )
   
  })
  
  
  # # Cria banco de dados para referência -------------------------------------
  # 
  # criar_bd_referencia <- reactive({
  #   
  #   if(banco$processar>0){
  #     
  # 
  #     atualizar_referencia <- T
  # 
  #     # if(is.null(configuracoes$parms_ref)) {
  #     # 
  #     # } else {
  #     # 
  #     #   parms_ref <- list()
  #     #   parms_ref[['fazenda_sel']] <- configuracoes$fazenda_sel
  #     # 
  #     #   if(is.null(qperdeu$input()$safra)) {
  #     # 
  #     #     parms_ref[['sistema']] <- list(sistema = 'all')
  #     # 
  #     #   } else {
  #     # 
  #     #     parms_ref[['sistema']] <- list(sistema = banco$fazenda %>% filter(safra == qperdeu$input()$safra))
  #     # 
  #     #   }
  #     # 
  #     #   parms_ref[['sistema']] <- ifelse(configuracoes$agrupamento == 'all', 'all', banco$fazenda)
  #     # 
  #     # 
  #     # }
  #     # 
  #     
  #     
  #     # if(!is.null(qperdeu$input()$safra)){
  #     #   
  #     #   if(is.null(configuracoes$qperdeu_safra)) {
  #     #     configuracoes$qperdeu_safra <- qperdeu$input()$safra
  #     #     atualizar_referencia <- F
  #     #   } else {
  #     #     
  #     #     if(configuracoes$agrupamento == '')
  #     #     
  #     #   }
  #     #   
  #     # }
  #     
  #     if(atualizar_referencia) {
  #       isolate({
  #         
  #         showModal(
  #           #lapiLoading()
  #           modalDialog('Aguarde enquanto os dados são processados.', tags$br(), lapiLoading(), class="lapi-loading" , easyClose = F, footer = NULL)  
  #         )
  #         
  #         fazenda_selecionada <- sel_one$fazenda_sel
  #         
  #         
  #         isolate({
  #           banco$fazenda <- banco$bd %>% filter(faz_id == fazenda_selecionada) %>% distinct
  #         })
  #         
  #         if(!is.null(sel_one$agrupamento)){
  #           
  #           if(sel_one$agrupamento != 'all'){
  #             
  #             if(sel_one$agrupamento == 'sistema') {
  #               
  #               isolate({
  #                 banco$ref <- banco$bd %>% 
  #                   filter(sistema == last(banco$fazenda$sistema)) 
  #               })
  #               
  #             } else if (sel_one$agrupamento == 'cluster') {
  #               
  #               banco$fazenda %>% 
  #                 distinct(safra, sistema, clust) %>% 
  #                 mutate(farm_clus = 1) -> clust_farm
  #               
  #               isolate({
  #                 banco$ref <- banco$bd %>% 
  #                   left_join(
  #                     clust_farm, by = c('safra', 'sistema', 'clust')
  #                   ) %>% 
  #                   filter(!is.na(farm_clus))
  #               })
  #             }
  #             
  #           } else {
  #             
  #             isolate({
  #               banco$ref <- banco$bd 
  #             })
  #             
  #           }
  #         }
  #         
  #         if(sel_one$intra_franquia == 's') {
  #           
  #           isolate({
  #             banco$ref <- banco$ref %>% filter(franqueado == banco$fazenda$franqueado %>% first)
  #           })
  #           
  #         }
  # 
  #         banco$ref %>% 
  #           filter(INDICADOR == "RESULTADO OPERAÇÃO PECUÁRIA (R$/HA) SE") %>% 
  #           group_by(safra) %>% 
  #           mutate(
  #             top30 = quantile(VALOR,probs = c(.7), na.rm = T),
  #             ref = ifelse(VALOR > top30, 1, 0)
  #           ) %>% 
  #           dplyr::select(TÉCNICO, franqueado, safra, nome, MUNICÍPIO, top30, ref) -> ref
  #         
  #         banco$ref %>%
  #           # filter(FRENTE != "REPRODUÇÃO") %>%
  #           # bind_rows(
  #           #   banco$ref %>%
  #           #     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, by = c("TÉCNICO", "franqueado", "safra", "nome")
  #         ) %>%
  #           right_join(
  #             banco$ind_top, by = c("FRENTE", "INDICADOR")
  #           ) %>%
  #           group_by(INDICADOR, safra, FRENTE, TOP) %>%
  #           nest %>%
  #           mutate(regua = purrr::pmap(.l=list(data, top = TOP), .f = calc_regua)) %>%
  #           unnest(regua) %>%
  #           arrange(safra, FRENTE, INDICADOR) -> regua
  #         
  #         # load('regua.Rdata')
  #         
  #         isolate({
  #           banco$regua <- regua %>% ungroup
  #           banco$indicadores <- regua %>% ungroup %>% select(FRENTE, INDICADOR) %>% distinct %>% arrange (FRENTE, INDICADOR) %>% mutate(variavel_id = 1:n())
  #         })
  #         
  #         tryCatch({
  #           
  #           banco$ref %>%
  #             filter(INDICADOR %in% c('GMD GLOBAL (Kg)', 'DESEMBOLSO CAB/MÊS')) %>% 
  #             select(safra, INDICADOR, VALOR, obs_id) %>%
  #             distinct %>% 
  #             group_by(safra,obs_id, INDICADOR) %>% 
  #             slice(1) %>% 
  #             ungroup %>% 
  #             spread(key = 'INDICADOR', value = 'VALOR') %>% 
  #             rename(desembolso = 3, gmd = 4) %>% 
  #             lm(desembolso~gmd * safra, data = .) -> banco$mod_gmd_des  
  #           
  #         }, error = function(e) {
  #           
  #           banco$mod_gmd_des <- NULL
  #           
  #         })
  #         
  #         shiny::removeModal()
  #         
  #       })   
  #     }
  #     
  #   }
  #   
  # })
  
  
 
  # Cria banco de dados para referência -------------------------------------
  # Lógica:
  # Se intrafranquia for selecionado filtrar as fazendas de uma mesma franquia
  # Se todas as fazendas forem escolhidas ler régua pré processada
  # Definir banco$ref
  # Definir banco$regua
  
  criar_bd_referencia <- reactive({
    if(banco$processar>0){
      
      isolate({
        
        showModal(
          modalDialog('Aguarde enquanto os dados são processados.', tags$br(), lapiLoading(), class="lapi-loading" , easyClose = F, footer = NULL)  
        )
        
        fazenda_selecionada <- sel_one$fazenda_sel
        
        isolate({
          banco$fazenda <- banco$bd %>% filter(faz_id == fazenda_selecionada) %>% distinct
        })
        
        referencias <- banco$bd
        ## primeiro definir a referencia
        if(sel_one$intra_franquia == 's') {
          referencias <- referencias %>% filter(franqueado == banco$fazenda$franqueado %>% first)
        }
        if(sel_one$agrupamento == "sistema"){
          sis <- last(banco$fazenda$sistema)
          referencias <- referencias %>% 
              filter(sistema == sis) 
        }else if (sel_one$agrupamento == 'cluster'){
          banco$fazenda %>% 
            distinct(safra, sistema, clust) %>% 
            mutate(farm_clus = 1) -> clust_farm
          referencias <- referencias %>% 
            left_join(
              clust_farm, by = c('safra', 'sistema', 'clust')
            ) %>% 
            filter(!is.na(farm_clus))
        }
        
        isolate({
          banco$ref <- referencias
        })
        
        # segundo definir a regua
        if(sel_one$intra_franquia != 's' && sel_one$agrupamento != "cluster"){
            if(sel_one$agrupamento == "all"){
              banco$regua <- rules('todas') 
            }else if(sel_one$agrupamento == "sistema"){
              if("CRIA-RECRIA-ENGORDA" %in% sis){
                banco$regua <- rules('ciclo_completo')
              }else if("RECRIA-ENGORDA" %in% sis){
                banco$regua <- rules('engorda')
              }else{
                banco$regua <- rules('cria')
              }
            }  
        }else{
          banco$ref %>% 
            filter(INDICADOR == "RESULTADO OPERAÇÃO PECUÁRIA (R$/HA) SE") %>% 
            group_by(safra) %>% 
            mutate(
              top30 = quantile(VALOR,probs = c(.7), na.rm = T),
              ref = ifelse(VALOR > top30, 1, 0)
            ) %>% 
            dplyr::select(TÉCNICO, franqueado, safra, nome, MUNICÍPIO, top30, ref) -> ref
          
          banco$ref %>%
            left_join(
              ref, by = c("TÉCNICO", "franqueado", "safra", "nome")
            ) %>%
            right_join(
              banco$ind_top, by = c("FRENTE", "INDICADOR")
            ) %>%
            group_by(INDICADOR, safra, FRENTE, TOP) %>%
            nest %>%
            mutate(regua = purrr::pmap(.l=list(data, top = TOP), .f = calc_regua)) %>%
            unnest(regua) %>%
            arrange(safra, FRENTE, INDICADOR) -> regua
          
          isolate({
            banco$regua <- regua %>% ungroup
          })
        }
        isolate({
          
          banco$indicadores <- banco$regua %>% select(FRENTE, INDICADOR) %>% distinct %>% arrange (FRENTE, INDICADOR) %>% mutate(variavel_id = 1:n())
        })
        
        
        tryCatch({
          
          banco$ref %>%
            filter(INDICADOR %in% c('GMD GLOBAL (Kg)', 'DESEMBOLSO CAB/MÊS')) %>% 
            select(safra, INDICADOR, VALOR, obs_id) %>%
            distinct %>% 
            group_by(safra,obs_id, INDICADOR) %>% 
            slice(1) %>% 
            ungroup %>% 
            spread(key = 'INDICADOR', value = 'VALOR') %>% 
            rename(desembolso = 3, gmd = 4) %>% 
            lm(desembolso~gmd * safra, data = .) -> banco$mod_gmd_des  
          
        }, error = function(e) {
          
          banco$mod_gmd_des <- NULL
          
        })
        
        shiny::removeModal()
        
      })   
      
      
    }
    
  })
  
  # Funcao para consolidar safra --------------------------------------------
  
  consolide_safras <- reactive({
    
    if(!is.null(historico$input()$sel_variavel)){
      
      if(!is.null(banco$processar) && banco$processar > 0){
        
        banco$fazenda %>%
          left_join(
            banco$indicadores, by = c("FRENTE", "INDICADOR")
          ) %>% 
          select(safra, INDICADOR, FRENTE, Fazenda = VALOR, variavel_id) %>%
          filter(variavel_id == historico$input()$sel_variavel) -> banco_var
        
        if(nrow(banco_var) == 0){
          return(NULL)
        }
        
        
        isolate({
          banco_var %>% 
            left_join(
              banco$regua, by = c('safra', 'INDICADOR', 'FRENTE')
            ) -> banco  
        })
        
        
        legendas <- tibble(
          names = c( 'hpd', 'ref', 'media', 'q50', 'q25', 'q75'),
          labels = c('Potencial', 'Top-rentáveis', 'Média', 'Mediana','Top25', 'Top75')
        )
        
        na.omit(match(c( 'hpd', 'ref', 'media', 'q50','q25', 'q75'), names(banco))) %>% as.numeric -> nomes_a_sub
        if(length(nomes_a_sub)>0) {
          names(banco)[nomes_a_sub] <- legendas %>% filter(names %in% names(banco)) %>% pull(labels)  
        }
        
        banco %>% 
          arrange(safra) %>% 
          mutate(ano = strsplit(safra, split = "/") %>% sapply(., '[[', 1) %>% as.numeric) %>% 
          select(safra, INDICADOR, FRENTE, TOP, unidade, ano, variavel_id, Mediana, Top75, Potencial, `Top-rentáveis`, Média, Fazenda, q70) %>% 
          pivot_longer(c(Mediana, Top75, Potencial, `Top-rentáveis`, Média, Fazenda, q70), names_to = 'key', values_to = 'value') %>% 
          nest(-key) %>% 
          mutate(
            fit = map(data, ~lm(value ~ ano, data = .x)),
            glance = map(fit, glance),
            tidied = map(fit, tidy)
          ) -> b1
          
        b1 %>% 
          unnest(tidied) %>% 
          filter(term == 'ano') -> b1a
        b1 %>%   
          unnest(glance) -> b1b
        
        b1b %>% 
          select(key, p.value, r2 = r.squared) %>% 
          left_join(
            b1a %>% 
              select(key, coef = estimate, std.error, p.modelo = p.value)    
          ) -> stats
        
       
        return(list(banco = banco, stats = stats))
      }  
    }
    
    
    
  })
  
  
  # Funcao para criar referencia --------------------------------------------
  
  rref <- reactive({
    
    if(!is.null(banco$fazenda)){
      
      banco$fazenda %>%
        filter(!FRENTE %in% c('AGRICULTURA', 'AGRICULTURA - PERFIL FINANCEIRO', 'CLIMA', 'COMPARATIVO SAFRA ANTERIOR')) %>%
        filter(INDICADOR %in% c('VALOR MÉDIO DE VENDA', 'GMD GLOBAL (Kg)', 'LOTAÇÃO GLOBAL UA/HA', 'DESEMBOLSO CAB/MÊS', 'RESULTADO OPERAÇÃO PECUÁRIA (R$/HA) SE')) %>%
        dplyr::select(safra, INDICADOR, VALOR) %>%
        distinct %>% 
        group_by(safra, INDICADOR) %>% 
        slice(1) %>% 
        ungroup %>% 
        spread(key = INDICADOR, value = VALOR) %>%
        arrange(safra) -> keyvars
      
      keyvars %>%
        select(-`RESULTADO OPERAÇÃO PECUÁRIA (R$/HA) SE`) %>%
        filter(complete.cases(.)) -> vars_ind
      
      banco$fazenda %>%
        dplyr::select(safra, sistema, clust) %>%
        distinct %>%
        full_join(
          vars_ind %>%
            select(safra) %>%
            mutate(present = T), by = 'safra'
        ) %>%
        filter(!is.na(present)) %>%
        select(-present) %>%
        left_join(
          banco$mc %>% rename(safra = SAFRA), by = c('sistema', 'clust', 'safra')
        ) %>%
        filter(!is.na(solucao)) %>%
        left_join(
          vars_ind %>%
            group_by(safra) %>%
            nest() %>% 
            rename(vars_ind = data), by = 'safra'
        ) %>%
        group_by(safra, sistema, clust) %>%
        mutate(ropse_calc = pmap(.l = list(boot = boot_simu, bootMed = boot_parms, dados = vars_ind), .f = possibly(pred_boot, otherwise = NULL))) %>% 
        mutate(data_sum = pmap(.l = list(data), .f = possibly(sum_keyvars, otherwise = NULL))) -> df
      
      
      df %>%
        unnest(ropse_calc,.drop = T) %>%
        ungroup %>%
        select(-sistema, -clust, -solucao) -> ropse_pred
      
      df %>%
        unnest(data_sum, .drop = T) %>%
        mutate(origem = 'ref') %>%
        ungroup %>%
        select(-sistema, -clust, -solucao) -> ref_desc
      
      keyvars %>%
        rename(desembolso = `DESEMBOLSO CAB/MÊS`, gmd = `GMD GLOBAL (Kg)`, lotacao = `LOTAÇÃO GLOBAL UA/HA`, ropse = `RESULTADO OPERAÇÃO PECUÁRIA (R$/HA) SE`, valormediovenda = `VALOR MÉDIO DE VENDA`) %>%
        mutate(origem = 'fazenda') %>%
        filter(complete.cases(.)) -> fazenda
      
      data_ropse <- ropse_pred %>%
        left_join(
          ref_desc %>%
            select(ropse_ref = ropse, safra), by = 'safra'
        ) %>%
        left_join(
          fazenda %>%
            select(ropse_faz = ropse, safra), by = 'safra'
        ) %>%
        select(-data, -boot_simu, -boot_parms, -vars_ind, -data_sum) %>% 
        filter(complete.cases(.))
      
      data_ind <- ref_desc %>%
        select(-ropse) %>%
        bind_rows(
          fazenda %>%
            select(-ropse)
        ) %>%
        select(safra, valormediovenda, gmd, lotacao, desembolso, origem) %>% 
        pivot_longer(c(valormediovenda, gmd, lotacao, desembolso), names_to = 'variavel', values_to = 'valor') %>% 
        spread(key = origem, value = valor) %>%
        as.data.frame %>%
        group_by(variavel) %>%
        nest %>%
        split(.$variavel)
      
      return(list(data_ropse = data_ropse, data_ind = data_ind))
      
    }
    
  })

  return(
    list(
      criar_bd_referencia = reactive({criar_bd_referencia()}),
      consolide_safras = reactive({consolide_safras()}),
      rref = reactive({rref()})
    )
  )

  
}
    
## To be copied in the UI
# mod_get_data_ui("get_data_ui_1")
    
## To be copied in the server
# callModule(mod_get_data_server, "get_data_ui_1")
 
