#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| viewerHeight: 800

library(shiny)
library(bslib)
library(dplyr)
library(ggplot2)
library(readr)
library(httr)
library(gt)
library(plotly)

# Function to load data with error handling and logging
carregar_dados <- function(url) {
  message("Tentando acessar URL: ", url)
  
  tryCatch({
    dados <- read_csv(url, 
                     col_types = cols(
                       Ano = col_character(),
                       Turma = col_character(),
                       Disciplina = col_character(),
                       Notas = col_double()
                     ),
                     locale = locale(decimal_mark = ",", 
                                   grouping_mark = "."))
    return(dados)
  }, error = function(e) {
    message("Erro ao carregar dados: ", e$message)
    dados_exemplo <- data.frame(
      Ano = rep(c("10º", "11º", "12º"), each = 100),
      Turma = rep(LETTERS[1:3], times = 100),
      Disciplina = rep(c("Matemática", "Português", "Inglês", "História", "Geografia"), times = 60),
      Notas = round(rnorm(300, mean = 14, sd = 3))
    )
    dados_exemplo$Notas[dados_exemplo$Notas < 0] <- 0
    dados_exemplo$Notas[dados_exemplo$Notas > 20] <- 20
    return(dados_exemplo)
  })
}

url <- "https://gist.githubusercontent.com/karlosgomes/3758e64d86522ae8e796ba490c8c111c/raw/d3c88aee7d0815814e666f5f71fd524c7e65198a/dados.csv"

dados <- carregar_dados(url) %>%
  filter(Disciplina != "Educação Moral e Religiosa")

# Preparar valores iniciais
ano_inicial <- unique(dados$Ano)[1]
disciplinas_iniciais <- dados %>%
  filter(Ano == ano_inicial) %>%
  pull(Disciplina) %>%
  unique() %>%
  sort()
turmas_iniciais <- dados %>%
  filter(Ano == ano_inicial,
         Disciplina == disciplinas_iniciais[1]) %>%
  pull(Turma) %>%
  unique() %>%
  sort()

ui <- page_sidebar(
  title = "Análise de Notas Escolares",
  theme = bs_theme(preset = "default"),
  fillable = TRUE,
  
  sidebar = sidebar(
    width = "200px",
    selectInput("ano", "Ano Escolar", 
                choices = unique(dados$Ano),
                selected = ano_inicial),
    selectInput("disciplina", "Disciplina",
                choices = disciplinas_iniciais,
                selected = disciplinas_iniciais[1]),
    selectInput("turma", "Turma", 
            choices = turmas_iniciais,
            selected = turmas_iniciais[1], # Change this line: select only first turma by default
            multiple = FALSE)
  ),
  
  layout_columns(
    fill = TRUE,
    height = "100px",
    value_box(
      title = "Média do Ano na Disciplina",
      value = textOutput("media_global"),
      theme = "primary"
    ),
    value_box(
      title = "Número de Notas do Ano na Disciplina",
      value = textOutput("n_notas"),
      theme = "secondary"
    ),
    value_box(
      title = "% Notas Positivas do Ano na Disciplina",
      value = textOutput("perc_positivas"),
      theme = "success"
    )
  ),
  
  layout_columns(
    fill = TRUE,
    heights_equal = "row",
    card(
      full_screen = TRUE,
      card_header("Disciplina na Turma Vs. Disciplina no Ano"),
      plotlyOutput("box_comparison")
    ),
    card(
      full_screen = TRUE,
      card_header("Análise da Disciplina"),
      gt_output("metrics_table")
    ),
    card(
      full_screen = TRUE,
      card_header("Distribuição das Notas da Turma"),
      plotlyOutput("histogram_plot")
    )
  )
)

server <- function(input, output, session) {
  # Update disciplinas based on ano
  observe({
    req(input$ano)
    disciplinas_do_ano <- dados %>%
      filter(Ano == input$ano) %>%
      pull(Disciplina) %>%
      unique() %>%
      sort()
    
    updateSelectInput(session, "disciplina",
                     choices = disciplinas_do_ano,
                     selected = disciplinas_do_ano[1])
  })
  
  # Update turmas based on ano and disciplina
  observe({
  req(input$ano, input$disciplina)
  turmas_disponiveis <- dados %>%
    filter(Ano == input$ano,
           Disciplina == input$disciplina) %>%
    pull(Turma) %>%
    unique() %>%
    sort()
    
    current_selected <- input$turma
  new_selected <- intersect(current_selected, turmas_disponiveis)
  if (length(new_selected) == 0) new_selected <- turmas_disponiveis[1]
  
  updateSelectInput(session, "turma",
                   choices = turmas_disponiveis,
                   selected = new_selected)
})
  
  dados_ano_disc <- reactive({
    req(dados, input$ano, input$disciplina)
    dados %>% 
      filter(Ano == input$ano,
             Disciplina == input$disciplina)
  })
  
  dados_filtrados <- reactive({
    req(dados)
    dados_temp <- dados_ano_disc()
    
    if (!is.null(input$turma) && length(input$turma) > 0)
      dados_temp <- dados_temp %>% filter(Turma %in% input$turma)
    
    dados_temp
  })
  
  output$media_global <- renderText({
    df <- dados_ano_disc()
    if (nrow(df) > 0) {
      media <- round(mean(df$Notas, na.rm = TRUE), 1)
      paste0(media, " valores")
    } else "N/A"
  })
  
  output$n_notas <- renderText({
    df <- dados_ano_disc()
    nrow(df)
  })
  
  output$perc_positivas <- renderText({
    df <- dados_ano_disc()
    if (nrow(df) > 0) {
      paste0(round(mean(df$Notas >= 10, na.rm = TRUE) * 100, 1), "%")
    } else "N/A"
  })
  
  output$box_comparison <- renderPlotly({
    req(input$ano, input$disciplina, length(input$turma) > 0)
    
    # Dados da turma na disciplina
    dados_turma <- dados_filtrados()
    
    # Dados do ano na disciplina
    dados_ano <- dados %>%
      filter(Ano == input$ano,
             Disciplina == input$disciplina)
    
    # Combinar os dados para o plot
    dados_plot <- bind_rows(
      mutate(dados_turma, Grupo = "Turma"),
      mutate(dados_ano, Grupo = "Ano")
    ) %>%
      mutate(Grupo = factor(Grupo, levels = c("Ano", "Turma")))
    
    # Criar o plot diretamente com plotly
    plot_ly(dados_plot, y = ~Grupo, x = ~Notas, type = "box",
            color = ~Grupo,
            colors = c("lightblue", "steelblue")) %>%
      layout(
        xaxis = list(title = "Notas", range = c(0, 20), dtick = 2),
        yaxis = list(title = ""),
        showlegend = FALSE,
        margin = list(t = 50, r = 50, b = 50, l = 50)
      )
  })
  
  output$metrics_table <- render_gt({
    req(nrow(dados_filtrados()) > 0, input$ano, input$disciplina, length(input$turma) > 0)
    
    media_ano_disciplina <- dados %>%
      filter(Ano == input$ano,
             Disciplina == input$disciplina) %>%
      summarise(media = mean(Notas, na.rm = TRUE)) %>%
      pull(media)
    
    media_turma_disciplina <- dados_filtrados() %>%
      summarise(media = mean(Notas, na.rm = TRUE)) %>%
      pull(media)
    
    media_turma_geral <- dados %>%
      filter(Ano == input$ano,
             Turma %in% input$turma) %>%
      summarise(media = mean(Notas, na.rm = TRUE)) %>%
      pull(media)
    
    media_geral_ano <- dados %>%
      filter(Ano == input$ano) %>%
      summarise(media = mean(Notas, na.rm = TRUE)) %>%
      pull(media)
    
    desvio_disciplina_ano <- media_turma_disciplina - media_ano_disciplina
    desvio_relativo_turma <- desvio_disciplina_ano - (media_turma_geral - media_geral_ano)
    
    metricas <- data.frame(
      Métrica = c(
        "Média da Turma na Disciplina",
        "Média do Ano na Disciplina",
        "Média Geral da Turma",
        "Média Geral do Ano",
        "Desvio para Média do Ano",
        "Desvio Relativo à Turma"
      ),
      Valor = c(
        round(media_turma_disciplina, 2),
        round(media_ano_disciplina, 2),
        round(media_turma_geral, 2),
        round(media_geral_ano, 2),
        round(desvio_disciplina_ano, 2),
        round(desvio_relativo_turma, 2)
      )
    )
    
    gt(metricas) %>%
      tab_header(
        title = md(paste("Métricas para", input$disciplina))
      ) %>%
      fmt_number(
        columns = "Valor",
        decimals = 2
      ) %>%
      tab_style(
        style = list(
          cell_fill(color = "lightgreen"),
          cell_text(weight = "bold")
        ),
        locations = cells_body(
          columns = "Valor",
          rows = Valor > 0 & (Métrica %in% c("Desvio para Média do Ano", "Desvio Relativo à Turma"))
        )
      ) %>%
      tab_style(
        style = list(
          cell_fill(color = "lightpink"),
          cell_text(weight = "bold")
        ),
        locations = cells_body(
          columns = "Valor",
          rows = Valor < 0 & (Métrica %in% c("Desvio para Média do Ano", "Desvio Relativo à Turma"))
        )
      ) %>%
      cols_align(
        align = "left",
        columns = "Métrica"
      ) %>%
      cols_align(
        align = "right",
        columns = "Valor"
      ) %>%
      tab_options(
        table.width = pct(100),
        column_labels.font.weight = "bold"
      )
  })
  
  output$histogram_plot <- renderPlotly({
    req(input$ano, input$disciplina, input$turma)
    
    dados_plot <- dados %>%
      filter(Ano == input$ano,
             Disciplina == input$disciplina,
             Turma %in% input$turma)
    
    plot_ly(dados_plot, x = ~Notas, type = "histogram",
            nbinsx = 20,
            marker = list(color = "steelblue",
                         line = list(color = "white", width = 1))) %>%
      layout(
        xaxis = list(title = "Notas", range = c(0, 20), dtick = 2),
        yaxis = list(title = "Frequência"),
        showlegend = FALSE,
        margin = list(t = 50, r = 50, b = 50, l = 50)
      )
  })
}

shinyApp(ui, server)