library(rio)

contratos = import("contratos-ancash-regional.xlsx")
# ============================================================
# 0) Paquetes, formateadores y tema
# ============================================================

# Instala una vez si hace falta:
# install.packages(c("tidyverse", "janitor", "scales", "lubridate", "ggrepel"))

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.2
## ✔ ggplot2   3.5.2     ✔ tibble    3.3.0
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.1.0     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(janitor)
## 
## Adjuntando el paquete: 'janitor'
## 
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library(scales)
## 
## Adjuntando el paquete: 'scales'
## 
## The following object is masked from 'package:purrr':
## 
##     discard
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
library(lubridate)
library(ggrepel)
library(ggplot2)

# Formateador de números abreviado (k, M, B, T)
fmt_num <- scales::label_number(scale_cut = scales::cut_short_scale())
# Alternativa prefijos SI:
# fmt_num <- scales::label_number(scale_cut = scales::cut_si(" "))

# Tema base
theme_set(theme_minimal(base_size = 12))

# ============================================================
# 1) Limpieza y derivación de variables
#    (Partimos de un data.frame llamado `contratos` en el ambiente)
# ============================================================

# Estandariza nombres
contratos <- contratos %>% clean_names()

# FECHA a Date, crea ANIO; MONTO a numérico
contratos <- contratos %>%
  mutate(
    fecha = as.Date(fecha),
    anio  = lubridate::year(fecha),
    monto = str_replace_all(monto, ",", "") %>% as.numeric()
  )

# Identifica columnas de empresas (empresa_1, empresa_2, ...)
cols_empresas <- contratos %>%
  select(starts_with("empresa_")) %>%
  names()

# Pasa empresas a formato largo y normaliza RUC a texto (evita notación científica)
emp_largo <- contratos %>%
  select(anio, all_of(cols_empresas), monto) %>%
  pivot_longer(
    cols = all_of(cols_empresas),
    names_to = "slot",
    values_to = "ruc_num"
  ) %>%
  filter(!is.na(ruc_num)) %>%
  mutate(ruc = sprintf("%.0f", as.numeric(ruc_num))) %>%  # RUC como string
  select(anio, ruc, monto)

# ============================================================
# 2) Métricas anuales base y panel integrado
# ============================================================

# a) Contratos y monto total por año
por_anio <- contratos %>%
  group_by(anio) %>%
  summarise(
    contratos   = n(),
    monto_total = sum(monto, na.rm = TRUE),
    .groups = "drop"
  )

# b) Empresas únicas activas por año
empresas_por_anio <- emp_largo %>%
  group_by(anio) %>%
  summarise(empresas_unicas = n_distinct(ruc), .groups = "drop")

# c) Tamaño promedio de consorcio por año (empresas por contrato)
tam_consorcio_prom <- contratos %>%
  mutate(id_contrato = row_number()) %>%
  left_join(
    contratos %>%
      mutate(id_contrato = row_number()) %>%
      select(id_contrato, all_of(cols_empresas)) %>%
      pivot_longer(cols = all_of(cols_empresas), values_to = "ruc_num") %>%
      filter(!is.na(ruc_num)) %>%
      group_by(id_contrato) %>%
      summarise(empresas_en_contrato = n(), .groups = "drop"),
    by = "id_contrato"
  ) %>%
  group_by(anio) %>%
  summarise(tam_consorcio_prom = mean(empresas_en_contrato, na.rm = TRUE), .groups = "drop")

# d) Panel integrado para gráficos
panel_anual <- por_anio %>%
  left_join(empresas_por_anio, by = "anio") %>%
  left_join(tam_consorcio_prom, by = "anio") %>%
  mutate(
    monto_promedio_x_contrato = monto_total / contratos,
    monto_x_empresa           = monto_total / empresas_unicas
  )

# ============================================================
# 3) Concentración por apariciones (HHI y Top-5)
#    *A falta de reparto de montos en consorcios*
# ============================================================

# Apariciones por empresa y año (cada contrato cuenta 1 por empresa participante)
apariciones <- emp_largo %>%
  group_by(anio, ruc) %>%
  summarise(apariciones = n(), .groups = "drop")

concentracion_anio <- apariciones %>%
  group_by(anio) %>%
  mutate(total_apar = sum(apariciones),
         cuota = apariciones / total_apar) %>%
  summarise(
    HHI        = sum(cuota^2),  # 0 a 1 (x10000 si quieres puntos HHI)
    top5_share = sum(sort(cuota, decreasing = TRUE)[1:min(5, dplyr::n())]),
    .groups = "drop"
  )

# ============================================================
# 4) Orden cronológico fijo (2004 -> ... -> 2024)
#    Convierte 'anio' en factor ordenado para TODOS los gráficos
# ============================================================

levels_anio <- sort(unique(panel_anual$anio))

panel_anual <- panel_anual %>%
  mutate(anio = factor(anio, levels = levels_anio))

concentracion_anio <- concentracion_anio %>%
  mutate(anio = factor(anio, levels = levels_anio))

# ============================================================
# 5) Helper de BARRAS HORIZONTALES (sin reordenar por valor)
#    Fix: geom_col(width = ...) en lugar de 'height'
#    Respeta el orden del factor 'anio' (cronológico)
# ============================================================

barh_anual <- function(data, x_val, y_anio = anio, x_lab = "", titulo = "",
                       formato = fmt_num, decimales = 0) {
  ggplot(data, aes(y = {{ y_anio }}, x = {{ x_val }}, fill = {{ x_val }})) +
    geom_col(width = 0.65, alpha = 0.95) +  # <- width (no height)
    geom_text(
      aes(label = if (is.null(formato)) round({{ x_val }}, decimales) else formato({{ x_val }})),
      hjust = -0.1, size = 3.2
    ) +
    scale_x_continuous(
      labels = formato,
      expand = expansion(mult = c(0, .08)),
      limits = c(0, max(dplyr::pull(data, {{ x_val }}), na.rm = TRUE) * 1.12)
    ) +
    scale_fill_gradient(low = "#AFCBFF", high = "#003f5c", guide = "none") +
    labs(title = titulo, x = x_lab, y = "Año") +
    theme(
      panel.grid.major.y = element_blank(),
      axis.line = element_line(),
      plot.title = element_text(face = "bold")
    )
}
# 6.1 Monto total adjudicado por año
barh_anual(
  panel_anual,
  x_val = monto_total,
  x_lab = "Monto total (PEN)",
  titulo = "Monto total adjudicado por año"
)

# 6.2 Número de contratos por año
barh_anual(
  panel_anual,
  x_val = contratos,
  x_lab = "Contratos",
  titulo = "Número de contratos por año",
  formato = label_comma(accuracy = 1)
)

# 6.3 Monto promedio por contrato
barh_anual(
  panel_anual,
  x_val = monto_promedio_x_contrato,
  x_lab = "PEN por contrato",
  titulo = "Monto promedio por contrato"
)

# 6.4 Empresas únicas por año
barh_anual(
  panel_anual,
  x_val = empresas_unicas,
  x_lab = "Empresas únicas",
  titulo = "Empresas únicas que contrataron por año",
  formato = label_comma(accuracy = 1)
)

# 6.5 Índice: monto total / número de empresas
barh_anual(
  panel_anual,
  x_val = monto_x_empresa,
  x_lab = "PEN por empresa (aprox.)",
  titulo = "Índice: monto total por empresa del año"
)

# 6.6 Tamaño promedio de consorcios por año
barh_anual(
  panel_anual,
  x_val = tam_consorcio_prom,
  x_lab = "Empresas por contrato (prom.)",
  titulo = "Tamaño promedio de consorcios por año",
  formato = label_number(accuracy = 0.1)
)

# 6.7 Participación acumulada del Top-5 (apariciones)
barh_anual(
  concentracion_anio,
  x_val = top5_share,
  x_lab = "Participación",
  titulo = "Participación del Top-5 de empresas (apariciones)",
  formato = percent_format(accuracy = 1)
)

# 6.8 Concentración por apariciones (HHI)
barh_anual(
  concentracion_anio,
  x_val = HHI,
  x_lab = "HHI (0–1)",
  titulo = "Concentración por apariciones (HHI, sin montos)",
  formato = percent_format(accuracy = 0.1)
)