library(shiny)
library(GLMBasedRaschEstimation)
library(readxl)
library(haven)
library(bslib)
library(DT)

ui <- page_sidebar(
  theme = bs_theme(version = 5, bootswatch = "flatly"),
  title = "Rasch Analysis Pro: GLM Estimation Suite",

  sidebar = sidebar(
    title = "Data Management",
    fileInput("upload", "1. Upload File (CSV, XLSX, SAV, DAT)",
              accept = c(".csv", ".xlsx", ".xls", ".sav", ".dat")),
    tags$hr(),
    actionButton("run_analysis", "2. Run Full Analysis",
                 class = "btn-success w-100", icon = icon("gears")),
    tags$hr(),
    uiOutput("item_selector_ui")
  ),

  navset_card_pill(
    title = "Analysis & Documentation",

    # --- Tab 1: Visualization ---
    nav_panel("Visualization Center", icon = icon("chart-line"),
              navset_underline(
                nav_panel("Standard ICC", card(plotOutput("standard_icc_plot", height = "500px"))),
                nav_panel("Rasch Advanced Curves", card(plotOutput("rasch_adv_plot", height = "500px")))
              )),

    # --- Tab 2: Statistics ---
    nav_panel("Statistics", icon = icon("table"),
              navset_underline(
                nav_panel("Ordered Difficulties", DTOutput("ordered_diff_table")),
                nav_panel("Subject Abilities", DTOutput("subject_abilities_table")),
                nav_panel("Model Summary", DTOutput("irt_table"))
              )),

    # --- Tab 3: About (Full Documentation) ---
    nav_panel("About", icon = icon("info-circle"),
              card(
                card_header("Package ‘GLMBasedRaschEstimation’ Documentation"),
                card_body(
                  h3("GLM-Based Estimation for Rasch Model Parameters"),
                  p(strong("Version:"), "0.1.2"),
                  p(strong("Description:"), "Provides functions for estimating Rasch model parameters using the Generalized Linear Model (GLM) framework. The methods implemented are based on Brown (2018, ISBN:978-3-319-93547-8) <doi:10.1007/978-3-319-93549-2> and Debelak et al. (2022, ISBN:978-1-138-71046-7) <doi:10.1201/9781315200620>."),
                  tags$hr(),
                  h4("Authors"),
                  tags$ul(
                    tags$li(strong("Ahmed Samir Megahed"), "[aut, cre] (Maintainer: Asamir@foe.zu.edu.eg)"),
                    tags$li(strong("Mustafa Ali Khalaf"), "[aut]"),
                    tags$li(strong("Ibraheem Mohamed Mougy"), "[aut]")
                  ),
                  tags$hr(),
                  h4("Technical Details"),
                  tags$ul(
                    tags$li(strong("License:"), "MIT + file LICENSE"),
                    tags$li(strong("Imports:"), "graphics, stats"),
                    tags$li(strong("Repository:"), "CRAN (Date: 2026-04-22)"),
                    tags$li(strong("Built with:"), "R 4.5.3 (2026-04-23)")
                  ),
                  tags$hr(),
                  h4("Links & Support"),
                  p(icon("github"), "URL:", a("https://github.com/DrAhmedSamir/GLMBasedRaschEstimation", href="https://github.com/DrAhmedSamir/GLMBasedRaschEstimation", target="_blank")),
                  p(icon("bug"), "Bug Reports:", a("https://github.com/DrAhmedSamir/GLMBasedRaschEstimation/issues", href="https://github.com/DrAhmedSamir/GLMBasedRaschEstimation/issues", target="_blank")),
                  tags$div(class = "alert alert-info",
                           icon("circle-info"),
                           strong("Note:"), "This version automatically detects and removes ID columns to ensure seamless processing.")
                )
              ))
  )
)

server <- function(input, output, session) {

  # Data Import
  raw_data <- reactive({
    req(input$upload)
    ext <- tools::file_ext(input$upload$name)
    df <- switch(ext,
                 csv  = read.csv(input$upload$datapath),
                 xlsx = read_excel(input$upload$datapath),
                 xls  = read_excel(input$upload$datapath),
                 sav  = read_sav(input$upload$datapath),
                 dat  = read.table(input$upload$datapath, header = TRUE),
                 as.data.frame(read.csv(input$upload$datapath))
    )
    return(as.data.frame(df))
  })

  # Analysis Pipeline with Auto-Cleaning
  analysis_results <- eventReactive(input$run_analysis, {
    req(raw_data())
    withProgress(message = 'Analyzing Data...', value = 0, {

      df_all <- raw_data()

      # Auto-detect numeric items and ID
      numeric_cols <- sapply(df_all, is.numeric)
      df_numeric <- df_all[, numeric_cols, drop = FALSE]
      subject_ids <- if("ID" %in% names(df_all)) df_all$ID else 1:nrow(df_all)

      # Core Rasch Functions
      prep <- prepare_data(df_numeric)
      fit <- fit_binary_irt(prep$matrix, prep$total_score)

      # Smoothing for Graphics
      theta_range <- seq(min(prep$total_score), max(prep$total_score), length.out = 100)
      probs_smooth <- compute_Modified_probabilities(fit, theta_range)
      logits_smooth <- rasch_logit(probs_smooth)

      # Data for Tables
      probs_orig <- compute_Modified_probabilities(fit, prep$total_score)
      logits_orig <- rasch_logit(probs_orig)
      ordered_diff <- extract_rasch_difficulties_ordered(logits_orig)

      abilities_table <- data.frame(
        ID = subject_ids,
        Raw_Score = prep$total_score,
        Ability_Logit = round(logits_orig[, "Row_Mean_Logit"], 4)
      )

      return(list(fit = fit, theta_range = theta_range,
                  probs_smooth = probs_smooth, logits_smooth = logits_smooth,
                  ordered_diff = ordered_diff, abilities = abilities_table))
    })
  })

  # UI Selector
  output$item_selector_ui <- renderUI({
    req(analysis_results())
    selectInput("selected_item", "3. Select Item for Plotting:", choices = analysis_results()$fit$Item)
  })

  # Rendering
  output$standard_icc_plot <- renderPlot({
    req(analysis_results(), input$selected_item)
    idx <- which(analysis_results()$fit$Item == input$selected_item)
    plot_item_curves(analysis_results()$theta_range, analysis_results()$probs_smooth[, idx, drop = FALSE], analysis_results()$fit[idx, , drop = FALSE])
  })

  output$rasch_adv_plot <- renderPlot({
    req(analysis_results(), input$selected_item)
    idx <- which(analysis_results()$fit$Item == input$selected_item)
    n_cols <- ncol(analysis_results()$logits_smooth)
    plot_rasch_curves(analysis_results()$probs_smooth[, idx, drop = FALSE], analysis_results()$logits_smooth[, c(idx, n_cols), drop = FALSE])
  })

  output$ordered_diff_table <- renderDT({ datatable(analysis_results()$ordered_diff) })
  output$subject_abilities_table <- renderDT({ datatable(analysis_results()$abilities) })
  output$irt_table <- renderDT({ datatable(analysis_results()$fit) })
}

shinyApp(ui, server)
