Panel badania: ujawnienia AI w GAMAM

Szkoła Główna Handlowa w Warszawie | 2026
Instrukcja: Interfejs umożliwia zdalne wykonanie skryptu na serwerze – wyniki obliczeń są na bieżąco wyświetlane w konsoli.
Istnieje również możliwość pobrania kompletnego pakietu replikacyjnego (skrypt, dane, wyniki) w celu weryfikacji lub własnych analiz.
Uruchomione badanie działa niezależnie od użytkownika. Kolejne uruchomienie możliwe jest po zakończeniu poprzedniego.
Skrypt badania
# =====================================================================
# MASTER SCRIPT  
# =====================================================================
#
# SPIS TREŚCI 
# 0. Instalacja i wczytanie bibliotek – wiersz 107
#    (ładowanie wszystkich niezbędnych pakietów)
# 1. Uniwersalny słownik – w. 125
#    (terminy ogólne, specyficzne, future, risk)
# 2. Funkcje pomocnicze – w. 208
#    (zliczanie terminów, słów, segmentacja zdań, synchronizacja kalendarzowa)
# 3. Analiza raportów 10-K (całe raporty) – w. 376
#    - Analiza całych raportów 10-K (gęstość AI na 1000 słów)
#    - Tabela 5: Liczba odniesień do AI
#    - Tabela 6: Gęstość na 1000 słów
#    - Tabela 6.1: Średnia dla grupy GAMAM
# 4. Analiza sekcji narracyjnych (Business, MD&A, Risk Factors) – w. 456
#    - Analiza gęstości AI w poszczególnych sekcjach
#    - Test Kruskala-Wallisa różnic między sekcjami
#    - Tabela H1: Porównanie sekcji narracyjnych vs finansowa
#    - Weryfikacja hipotezy H1
# 5. Analiza raportów 10-Q – w. 549
#    - Synchronizacja kalendarzowa (rok fiskalny → kalendarzowy)
#    - Agregacja roczna (Q1-Q3)
#    - Tabela 10: Gęstość 10-Q
#    - Tabela 10.1: Średnia GAMAM (10-Q)
# 6. Analiza Earnings Calls – w. 697
#    - Synchronizacja kalendarzowa (rok fiskalny → kalendarzowy)
#    - Podział na presentation i Q&A
#    - Tabela 13: Gęstość EC (średnia roczna)
#    - Tabela 13.1: Średnia GAMAM (EC)
#    - Tabela 13.2: Podział presentation/Q&A
#    - Korelacja Spearmana: presentation vs Q&A
#    - Porównanie EC vs 10-K - weryfikacja H2
# 7. Korelacje ujawnień z R&D i CAPEX (H3) – w. 913
#    - Korelacje Spearmana (globalne i wewnątrz spółek)
#    - Regresja panelowa Fixed Effects (10-K)
#      * Model CAPEX (surowy)
#      * Model R&D (surowy)
#      * Model łączny CAPEX + R&D
#      * Modele log-log
#      * Model z efektami czasowymi
#    - Test Hausmana (FE vs RE)
#    - Test F (FE vs Pooled OLS)
#    - Tabela 16: Korelacje Spearmana dla EC
#    - Tabela 17: Modele panelowe dla EC
#    - Weryfikacja hipotezy H3
# 8. Analiza jakościowa (Future/Risk, General/Specific) – w. 1182
#    - Analiza kontekstu: Future i Risk w zdaniach z AI
#    - Podział na terminy ogólne i specyficzne
#    - Tabela 22: Średnia dla grupy GAMAM (ważona)
#    - Tabela 23: Podział na spółki (ważony)
# 9. Event Study – w. 1221
#    - Obliczanie CAR dla okien [-1,+1], [-3,+3], [-5,+5]
#    - Podział na HIGH/LOW według mediany gęstości AI
#    - Tabele 26 i 25: Test hipotezy H4 (regresja + Mann-Whitney)
#    - CAAR (średnie CAR) z testem t
#    - Regresja CAR (M1, M2, M3)
#    - Tabela 27: Test BMP
#    - Analiza wolumenu obrotu (zmiana procentowa)
#    - Specyfikacja T+0 (dzień publikacji)
#    - Specyfikacja bez roku 2022
#    - Test Placebo
#    - Test Corrado
#    - Alternatywne testy statystyczne dla H4:
#      * Test permutacyjny 
#      * Bayes Factor 
#      * Regresja kwantylowa (mediana)
#      * Bootstrapowy przedział ufności (95%)
#      * Analiza zmiany intensywności (delta_density)
# 10. Funkcja główna main() – w. 2451
# 
#    Format plików w poszczególnych załącznikach:
#    - pkt 3 (10-K, całe raporty) → .txt
#    - pkt 4 (10-K, sekcje narracyjne) → .txt
#    - pkt 5 (10-Q) → .pdf
#    - pkt 6 (Earnings calls) → .txt
#    - pkt 7 (Korelacje z R&D/CAPEX) → dane z pkt 3 i 6 (brak własnych plików)
#    - pkt 8 (Analiza jakościowa) → dane z pkt 3 i 6 (brak własnych plików)
#    - pkt 9 (Event Study) → .pdf (10-K i 10-Q) + .txt (Earnings calls) + .csv + .xlsx
#    Wymagane nazwy plików (przykłady):
#    - pkt 3 (10-K, cały raport):     `10-K 2024 Microsoft.txt`
#    - pkt 4 (sekcje narracyjne):     
#      * Business:   `Microsoft 2025 10-K Business.txt`
#      * MD&A:       `Microsoft 2025 10-K MD&A.txt`
#      * Risk:       `Microsoft 2025 10-K Risk Factors.txt`
#    - pkt 5 (10-Q):                  `10-Q3 2023 Alphabet.pdf`
#    - pkt 6 (Earnings calls):        `Amazon_2023_Q2_earnings.txt`
#    - pkt 9 (Event Study):
#      * 10-K (.pdf):                 `10-K 2024 Apple.pdf`
#      * 10-Q (.pdf):                 `10-Q2 2022 Meta.pdf`
#      * Earnings calls (.txt):       `Alphabet_2023_Q2_earnings.txt`
#      * Dane cenowe (.csv):          `AAPL_US.csv`, `MSFT_US.csv`, `GOOGL_US.csv`, 
#                                      `AMZN_US.csv`, `META_US.csv`, `SPX_US.csv`
#      * Daty zdarzeń i EPS_suprise (.xlsx):        `mag_tabele_i_wykresy.xlsx`
# =====================================================================



# ŚCIEŻKI
folder_10k       <- "10K"
folder_narrative <- "Business - Risk Factors - MD&A"
folder_10q       <- "10-Q"
folder_ec        <- "earnings_calls"
folder_prices    <- "event_study"

# =====================================================================
# 0. INSTALACJA I WCZYTANIE BIBLIOTEK
# =====================================================================

required_packages <- c(
  "stringr", "tidyr", "dplyr", "lubridate",
  "plm", "lmtest", "sandwich", "pdftools", 
  "readxl", "quantreg", "car", "clubSandwich", 
  "BayesFactor"
)

# Bezpieczne ładowanie pakietów bez prób ich reinstalacji
suppressPackageStartupMessages({ for (pkg in required_packages) {
  if (!require(pkg, character.only = TRUE)) {
    stop(paste("Błąd krytyczny: Brak pakietu", pkg, "na serwerze!"))
  }
} })

# =====================================================================
# 1. SŁOWNIK
# =====================================================================

# --- Terminy ogólne ---
AI_TERMS_GENERAL <- c(
  # --- Terminy ogólne i strategiczne ---
  "artificial intelligence", "\\bai\\b", "\\bai-", "machine intelligence", 
  "cognitive computing", "sovereign ai", "ai strategy", "ai investment", 
  "ai initiative", "ai research",
  
  # --- Uczenie maszynowe i Architektura ---
  "machine learning", "\\bml\\b", "supervised learning", "unsupervised learning",
  "reinforcement learning", "deep learning", "neural network", "neural networks",
  "\\bcnn\\b", "\\brnn\\b", "transformer model", "attention mechanism",
  "neural engine", "\\bnpu\\b"
)


# --- Terminy specyficzne (Specific) ---
AI_TERMS_SPECIFIC <- c(
  # --- Generatywna AI i Agenci ---
  "generative ai", "\\bgenai\\b", "generative model", "diffusion model",
  "large language model", "large language models", "\\bllm\\b", "\\bllms\\b",
  "foundation model", "multimodal model", "\\bgpt\\b", "\\bchatgpt\\b", "\\bai agent\\b", 
  "agentic ai", "context window", "parameter count",
  
  # --- Procesy modelowe i Interakcja ---
  "model training", "inference engine", "fine-tuning", "pre-training", 
  "model deployment", "\\bprompting\\b", "\\btokenization\\b", "cost per token",
  
  # --- Infrastruktura AI ---
  "ai compute", "\\bgpu\\b", "\\bgpus\\b", "\\btpu\\b", "compute cluster",
  "data pipeline", "data labeling", "ai workloads", "ai platform", 
  "on-device ai", "edge ai",
  
  # --- Zastosowania ---
  "autonomous systems", "recommendation engine", "algorithmic recommendation",
  "anomaly detection", "predictive analytics",
  
  # --- Ryzyka, etyka i bezpieczeństwo ---
  "model risk", "model bias", "\\bexplainability\\b", "\\bhallucination\\b",
  "responsible ai", "ethical ai", "ai governance", "ai compliance",
  "adversarial attack", "data poisoning",
  
  # --- Brand Terms - Alphabet ---
  "google ai", "\\bgemini\\b", "\\bbard\\b", "\\bdeepmind\\b", "vertex ai", "\\bpaalm\\b", "tpu v5",
  
  # --- Brand Terms - Microsoft ---
  "microsoft ai", "\\bcopilot\\b", "azure ai", "\\bopenai\\b", "\\bphi–3\\b", "copilot\\+",
  
  # --- Brand Terms - Meta ---
  "meta ai", "\\bllama\\b", "\\bpytorch\\b", "segment anything", "superintelligence",
  
  # --- Brand Terms - Amazon ---
  "amazon ai", "\\balexa\\b", "amazon q", "aws ai", "\\bbedrock\\b", "\\btitan\\b",
  
  # --- Brand Terms - Apple ---
  "apple intelligence", "\\bsiri\\b", "\\bajax\\b"
)

ALL_AI_TERMS <- c(AI_TERMS_GENERAL, AI_TERMS_SPECIFIC)
ALL_AI_TERMS_SORTED <- ALL_AI_TERMS[order(nchar(ALL_AI_TERMS), decreasing = TRUE)]

FUTURE_INDICATORS <- c(
  "will", "expect", "anticipate", "plan", "intend", "goal", "target",
  "outlook", "guidance", "pipeline", "roadmap", "future", "upcoming",
  "next year", "next quarter", "long-term", "strategic", "opportunity",
  "potential", "going forward", "looking ahead", "we believe",
  "we project", "we forecast", "we aim", "committed to", "investing in",
  "expanding", "scaling", "ramp up"
)

RISK_INDICATORS <- c(
  "risk", "risks", "uncertainty", "uncertainties", "challenge", "challenges",
  "concern", "concerns", "threat", "threats", "exposure", "vulnerability",
  "vulnerabilities", "caution", "cautionary", "subject to", "potential adverse", "adverse", "difficult", "difficulties",
  "complex", "complexity", "regulatory", "regulation", "compliance",
  "ethical", "bias", "hallucination", "misuse", "abuse", "safeguard",
  "mitigate", "mitigation", "unforeseen", "unexpected", "volatile",
  "disruption", "liability", "litigation", "may", "could", "might"
)

# =====================================================================
# 2. FUNKCJE POMOCNICZE
# =====================================================================

count_terms <- function(text, terms_list) {
  if (is.na(text) || nchar(text) == 0) return(0)
  text_clean <- clean_text(text)
  total_count <- 0
  for (term in terms_list) {
    if (grepl("\\\\b", term)) {
      pattern <- term
    } else if (grepl(" ", term)) {
      term_regex <- str_replace_all(term, " ", "\\\\s+")
      pattern <- paste0("\\b", term_regex, "\\b")
    } else {
      pattern <- paste0("\\b", term, "\\b")
    }
    count <- str_count(text_clean, pattern)
    total_count <- total_count + count
    text_clean <- str_remove_all(text_clean, pattern)
  }
  return(total_count)
}

count_words <- function(text) {
  if (is.na(text) || nchar(text) == 0) return(0)
  return(length(str_split(tolower(text), "\\s+")[[1]]))
}

calculate_density <- function(mentions, words) {
  result <- ifelse(words > 0, (mentions / words) * 1000, 0)
  return(round(result, 2))
}

count_terms_with_details <- function(text, terms_list) {
  text_lower <- tolower(text)
  total_count <- 0
  term_counts <- list()
  
  clean_length <- function(t) {
    nchar(str_replace_all(t, "\\\\b", ""))
  }
  sorted_terms <- terms_list[order(sapply(terms_list, clean_length), decreasing = TRUE)]
  
  for (term in sorted_terms) {
    if (str_detect(term, "^\\\\b")) {
      pattern <- term
    } else {
      pattern <- paste0("\\b", str_replace_all(term, "([.\\\\+*?\\[\\^\\]$()])", "\\\\\\1"), "\\b")
    }
    
    matches <- str_extract_all(text_lower, regex(pattern, ignore_case = TRUE))[[1]]
    count <- length(matches)
    
    if (count > 0) {
      total_count <- total_count + count
      term_counts[[term]] <- count
      text_lower <- str_replace_all(text_lower, regex(pattern, ignore_case = TRUE), "")
    }
  }
  return(list(total = total_count, counts = term_counts))
}

ABBREVIATIONS <- c("Mr", "Mrs", "Ms", "Dr", "Prof", "Inc", "Corp", "Co", "Ltd",
                   "Jan", "Feb", "Mar", "Apr", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
                   "e.g", "i.e", "vs", "etc")

split_into_sentences <- function(text) {
  text <- str_replace_all(text, "\\.{3,}", "___ELLIPSIS___")
  for (abbr in ABBREVIATIONS) {
    text <- str_replace_all(text, paste0("\\b", abbr, "\\."), paste0(abbr, "___DOT___"))
  }
  text <- str_replace_all(text, "(\\d)\\.(\\d)", "\\1___DECIMAL___\\2")
  sentences <- str_split(text, "(?<=[.!?])\\s+")[[1]]
  sentences <- str_replace_all(sentences, "___DOT___", ".")
  sentences <- str_replace_all(sentences, "___DECIMAL___", ".")
  sentences <- str_replace_all(sentences, "___ELLIPSIS___", "...")
  sentences <- sentences[str_trim(sentences) != ""]
  return(sentences)
}

sentence_has_ai <- function(sentence, terms_list) {
  sentence_lower <- tolower(sentence)
  for (term in terms_list) {
    if (grepl("\\\\b", term)) {
      if (str_detect(sentence_lower, regex(term, ignore_case = TRUE))) return(TRUE)
    } else {
      if (str_detect(sentence_lower, regex(paste0("\\b", term, "\\b"), ignore_case = TRUE))) return(TRUE)
    }
  }
  return(FALSE)
}

analyze_qualitative <- function(text, company, year, doc_type) {
  total_words <- count_words(text)
  result <- count_terms_with_details(text, ALL_AI_TERMS_SORTED)
  total_ai_count <- result$total
  term_counts <- result$counts
  
  general_count <- 0
  specific_count <- 0
  for (term in names(term_counts)) {
    if (term %in% AI_TERMS_GENERAL) {
      general_count <- general_count + term_counts[[term]]
    } else if (term %in% AI_TERMS_SPECIFIC) {
      specific_count <- specific_count + term_counts[[term]]
    }
  }
  
  ai_per_1000 <- if (total_words > 0) (total_ai_count / total_words) * 1000 else 0
  if (total_ai_count > 0) {
    pct_general <- (general_count / total_ai_count) * 100
    pct_specific <- (specific_count / total_ai_count) * 100
  } else {
    pct_general <- 0
    pct_specific <- 0
  }
  
  sentences <- split_into_sentences(text)
  future_count <- 0
  risk_count <- 0
  ai_sentences <- 0
  for (sentence in sentences) {
    if (sentence_has_ai(sentence, ALL_AI_TERMS_SORTED)) {
      ai_sentences <- ai_sentences + 1
      sent_lower <- tolower(sentence)
      if (any(sapply(FUTURE_INDICATORS, function(x) grepl(x, sent_lower, fixed = TRUE)))) future_count <- future_count + 1
      if (any(sapply(RISK_INDICATORS, function(x) grepl(x, sent_lower, fixed = TRUE)))) risk_count <- risk_count + 1
    }
  }
  
  pct_future <- if (ai_sentences > 0) round(future_count / ai_sentences * 100, 1) else 0
  pct_risk <- if (ai_sentences > 0) round(risk_count / ai_sentences * 100, 1) else 0
  
  return(data.frame(
    company = company, year = year, doc_type = doc_type,
    total_words = total_words, total_ai = total_ai_count,
    AI_Total = total_ai_count,                    
    AI_Specific_Count = specific_count,           
    AI_General_Count = general_count,             
    AI_Sentences_Count = ai_sentences,            
    Future_Count = future_count,                  
    Risk_Count = risk_count,                      
    mentions = total_ai_count, words = total_words, density = round(ai_per_1000, 2),
    pct_general = round(pct_general, 1), pct_specific = round(pct_specific, 1),
    pct_future = pct_future, pct_risk = pct_risk,
    stringsAsFactors = FALSE
  ))
}

sync_calendar <- function(fiscal_year, fiscal_quarter, company) {
  cal_year <- as.numeric(fiscal_year)
  cal_quarter <- fiscal_quarter
  
  if (company == "MSFT") {
    if (fiscal_quarter == "Q1") { cal_quarter <- "Q3"; cal_year <- cal_year - 1 }
    else if (fiscal_quarter == "Q2") { cal_quarter <- "Q4"; cal_year <- cal_year - 1 }
    else if (fiscal_quarter == "Q3") { cal_quarter <- "Q1" }
    else if (fiscal_quarter == "Q4") { cal_quarter <- "Q2" }
  } else if (company == "AAPL") {
    if (fiscal_quarter == "Q1") { cal_quarter <- "Q4"; cal_year <- cal_year - 1 }
    else if (fiscal_quarter == "Q2") { cal_quarter <- "Q1" }
    else if (fiscal_quarter == "Q3") { cal_quarter <- "Q2" }
    else if (fiscal_quarter == "Q4") { cal_quarter <- "Q3" }
  }
  return(list(year = as.character(cal_year), quarter = cal_quarter))
}

# =====================================================================
# 3. ANALIZA RAPORTÓW 10-K
# =====================================================================

clean_text <- function(text) {
  if (is.na(text) || nchar(text) == 0) return("")
  text %>%
    tolower() %>%
    str_replace_all("[\r\n\t]", " ") %>%
    str_replace_all("\\s+", " ") %>%
    str_trim()
}

read_document_text <- function(file_path) {
  if (grepl("\\.pdf$", file_path, ignore.case = TRUE)) {
    pages <- pdftools::pdf_text(file_path)
    pages <- pages[nchar(pages) > 20]
    text <- paste(pages, collapse = " ")
    text <- gsub("([a-zA-Z])-\\s+([a-zA-Z])", "\\1\\2", text)
    text <- gsub("([a-zA-Z])-\\n+([a-zA-Z])", "\\1\\2", text)
    text <- gsub("[\r\n\t]", " ", text)
    text <- gsub("\\s+", " ", text)
    text <- iconv(text, from = "UTF-8", to = "ASCII", sub = " ")
    return(clean_text(text))
  } else {
    text <- paste(readLines(file_path, warn = FALSE), collapse = " ")
    return(clean_text(text))
  }
}

analyze_10k_full <- function(folder_path) {
  cat("\n", strrep("=", 70), "\n")
  cat("ZAŁĄCZNIK 2 – ANALIZA RAPORTÓW 10-K (CAŁE RAPORTY)\n")
  cat(strrep("=", 70), "\n")
  
  files <- list.files(folder_path, pattern = "\\.txt$", full.names = TRUE, ignore.case = TRUE)
  results <- list()
  
  for (file in files) {
    name <- basename(file)
    company <- case_when(
      grepl("Alphabet", name) ~ "GOOGL",
      grepl("Amazon", name) ~ "AMZN",
      grepl("Apple", name) ~ "AAPL",
      grepl("Meta", name) ~ "META",
      grepl("Microsoft", name) ~ "MSFT",
      TRUE ~ NA_character_
    )
    year <- str_extract(name, "202[2-5]")
    if (is.na(company) || is.na(year)) next
    
    cat("Przetwarzam:", company, year, "-", name, "\n")
    text <- read_document_text(file)
    if (nchar(text) == 0) next
    
    result <- analyze_qualitative(text, company, year, "10-K")
    results[[length(results) + 1]] <- result
    cat("  → AI:", result$total_ai, "| gęstość:", result$density, "| Future:", result$pct_future, "% | Risk:", result$pct_risk, "%\n")
  }
  
  if (length(results) == 0) return(NULL)
  df <- bind_rows(results)
  
  cat("\n--- TABELA 5: Liczba odniesień (10-K) ---\n")
  table_5 <- df %>% select(company, year, total_ai) %>%
    pivot_wider(names_from = year, values_from = total_ai, values_fill = 0) %>%
    mutate(avg_2022_2025 = round((`2022`+`2023`+`2024`+`2025`)/4, 0))
  print(table_5)
  
  cat("\n--- TABELA 6: Gęstość na 1000 słów (10-K) ---\n")
  table_6 <- df %>% select(company, year, density) %>%
    pivot_wider(names_from = year, values_from = density, values_fill = 0) %>%
    mutate(avg_2022_2025 = round((`2022`+`2023`+`2024`+`2025`)/4, 2))
  print(table_6)
  
  cat("\n--- TABELA 6.1: Średnia GAMAM (10-K) ---\n")
  table_7 <- df %>% group_by(year) %>% summarise(gamam_avg_density = round(mean(density), 2))
  print(table_7)
  
  return(df)
}

# =====================================================================
# 4. ANALIZA RAPORTÓW 10-K - SEKCJE NARRACYJNE
# =====================================================================

analyze_narrative_sections <- function(folder_path, results_full_10k) {
  cat("\n", strrep("=", 70), "\n")
  cat("ZAŁĄCZNIK 2.1 – SEKCJE NARRACYJNE (Business, MD&A, Risk Factors)\n")
  cat(strrep("=", 70), "\n")
  
  files <- list.files(folder_path, pattern = "\\.txt$", full.names = TRUE)
  results <- list()
  
  for (file in files) {
    name <- basename(file)
    parts <- str_split(str_replace(name, "\\.txt$", ""), " ")[[1]]
    
    company <- case_when(
      grepl("MICROSOFT", parts[1], ignore.case = TRUE) ~ "MSFT",
      grepl("ALPHABET|GOOGLE", parts[1], ignore.case = TRUE) ~ "GOOGL",
      grepl("AMAZON", parts[1], ignore.case = TRUE) ~ "AMZN",
      grepl("APPLE", parts[1], ignore.case = TRUE) ~ "AAPL",
      grepl("META|FACEBOOK", parts[1], ignore.case = TRUE) ~ "META",
      TRUE ~ NA_character_
    )
    year <- parts[2]
    section <- parts[4]
    if (is.na(company)) next
    
    cat("Przetwarzam:", company, year, "- sekcja:", section, "\n")
    text <- paste(readLines(file, warn = FALSE), collapse = " ")
    if (nchar(text) == 0) next
    
    ai_count <- count_terms(text, ALL_AI_TERMS_SORTED)
    word_count <- count_words(text)
    density <- calculate_density(ai_count, word_count)
    
    results[[length(results) + 1]] <- data.frame(
      company = company, year = year, section = section,
      ai_count = ai_count, word_count = word_count, density = density,
      stringsAsFactors = FALSE
    )
    cat("  → AI:", ai_count, "| gęstość:", density, "\n")
  }
  
  if (length(results) == 0) return(NULL)
  df <- bind_rows(results)
  
  cat("\n--- TABELA 7: Średnia gęstość w poszczególnych sekcjach ---\n")
  table_sections <- df %>% group_by(section, year) %>%
    summarise(srednia_gestosc = round(mean(density), 2), .groups = "drop") %>%
    pivot_wider(names_from = year, values_from = srednia_gestosc, values_fill = 0)
  print(table_sections)
  
  for (rok in c("2022", "2023", "2024", "2025")) {
    dane_rok <- df %>% filter(year == rok)
    if (nrow(dane_rok) >= 3 && length(unique(dane_rok$section)) >= 3) {
      kw_test <- kruskal.test(density ~ section, data = dane_rok)
      cat(paste("Rok", rok, "- p-value =", round(kw_test$p.value, 4)))
      if (kw_test$p.value < 0.05) cat(" ✅ Istotne różnice\n") else cat(" ❌ Brak istotnych różnic\n")
    }
  }
  
  narrative_sum <- df %>% group_by(company, year) %>%
    summarise(narrative_ai = sum(ai_count), narrative_words = sum(word_count),
              narrative_density = calculate_density(narrative_ai, narrative_words), .groups = "drop")
  
  h1_data <- results_full_10k %>% select(company, year, total_ai, total_words, density) %>%
    left_join(narrative_sum, by = c("company", "year")) %>%
    mutate(
      other_ai = total_ai - narrative_ai,
      other_words = total_words - narrative_words,
      other_density = calculate_density(other_ai, other_words)
    )
  
  cat("\n--- TABELA 8: Porównanie sekcji narracyjnych vs finansowa ---\n")
  h1_summary <- h1_data %>% group_by(year) %>%
    summarise(
      narrative_avg = round(mean(narrative_density, na.rm = TRUE), 2),
      other_avg = round(mean(other_density, na.rm = TRUE), 2),
      total_avg = round(mean(density, na.rm = TRUE), 2)
    )
  print(h1_summary)
  
  narrative_2025 <- h1_summary %>% filter(year == 2025) %>% pull(narrative_avg)
  other_2025 <- h1_summary %>% filter(year == 2025) %>% pull(other_avg)
  cat("\n✅ Hipoteza H1: Gęstość w sekcjach narracyjnych (", narrative_2025, 
      ") > finansowa (", other_2025, ") → POTWIERDZONA\n", sep="")
  
  return(list(sections = df, h1 = h1_summary))
}

# =====================================================================
# 5. ANALIZA RAPORTÓW 10-Q
# =====================================================================

analyze_10q_full <- function(folder_path) {
  cat("\n", strrep("=", 70), "\n")
  cat("ZAŁĄCZNIK 3 – ANALIZA RAPORTÓW 10-Q\n")
  cat(strrep("=", 70), "\n")
  
  clean_text <- function(text) {
    text %>%
      tolower() %>%
      str_replace_all("[\r\n]", " ") %>%
      str_replace_all("\\s+", " ") %>%
      str_trim()
  }
  
  read_pdf_text_improved <- function(pdf_path) {
    pages <- pdftools::pdf_text(pdf_path)
    pages <- pages[nchar(pages) > 20]
    text <- paste(pages, collapse = " ")
    text <- gsub("([a-zA-Z])-\\s+([a-zA-Z])", "\\1\\2", text)
    text <- gsub("([a-zA-Z])-\\n+([a-zA-Z])", "\\1\\2", text)
    text <- gsub("[\r\n\t]", " ", text)
    text <- gsub("\\s+", " ", text)
    text <- iconv(text, from = "UTF-8", to = "ASCII", sub = " ")
    text <- clean_text(text)
    return(text)
  }
  
  count_terms_10q <- function(text, terms_list) {
    text_clean <- clean_text(text)
    total_count <- 0
    for (term in terms_list) {
      if (grepl("\\\\b", term)) {
        pattern <- term
      } else {
        term_regex <- str_replace_all(term, " ", "\\\\s+")
        pattern <- paste0("\\b", term_regex, "\\b")
      }
      count <- str_count(text_clean, regex(pattern, ignore_case = TRUE))
      total_count <- total_count + count
      text_clean <- str_remove_all(text_clean, regex(pattern, ignore_case = TRUE))
    }
    return(total_count)
  }
  
  count_words_10q <- function(text) {
    text_clean <- clean_text(text)
    words <- str_split(text_clean, "\\s+")[[1]]
    words <- words[words != ""]
    return(length(words))
  }
  
  extract_calendar_period <- function(filename, company) {
    name <- basename(filename)
    fy <- as.numeric(str_extract(name, "202[2-6]"))
    fq <- str_extract(name, "Q[1-4]")
    if (is.na(fq)) fq <- "Q1" 
    
    cal_year <- fy
    cal_quarter <- fq
    
    if (company == "MSFT") {
      if (fq == "Q1") { cal_quarter <- "Q3"; cal_year <- fy - 1 }
      else if (fq == "Q2") { cal_quarter <- "Q4"; cal_year <- fy - 1 }
      else if (fq == "Q3") { cal_quarter <- "Q1" }
      else if (fq == "Q4") { cal_quarter <- "Q2" }
    } else if (company == "AAPL") {
      if (fq == "Q1") { cal_quarter <- "Q4"; cal_year <- fy - 1 }
      else if (fq == "Q2") { cal_quarter <- "Q1" }
      else if (fq == "Q3") { cal_quarter <- "Q2" }
      else if (fq == "Q4") { cal_quarter <- "Q3" }
    }
    return(list(year = as.character(cal_year), quarter = cal_quarter))
  }
  
  extract_company_10q <- function(filename) {
    name <- toupper(basename(filename))
    if (grepl("META", name)) return("META")
    if (grepl("GOOGL|GOOG|ALPHABET", name)) return("GOOGL")
    if (grepl("MSFT|MICROSOFT", name)) return("MSFT")
    if (grepl("AMZN|AMAZON", name)) return("AMZN")
    if (grepl("AAPL|APPLE", name)) return("AAPL")
    return("UNKNOWN")
  }
  
  files <- list.files(folder_path, pattern = "\\.pdf$", full.names = TRUE, ignore.case = TRUE)
  results <- list()
  
  for (file in files) {
    company <- extract_company_10q(file)
    if (company == "UNKNOWN") next
    
    period <- extract_calendar_period(file, company)
    year <- period$year
    quarter <- period$quarter
    
    if (is.na(year) || !year %in% c("2022", "2023", "2024", "2025")) next
    
    cat("Przetwarzam:", company, "→ CY", year, quarter, "-", basename(file), "\n")
    
    text <- read_pdf_text_improved(file)
    if (nchar(text) < 100) next
    
    mentions <- count_terms_10q(text, ALL_AI_TERMS_SORTED)
    words <- count_words_10q(text)
    density <- ifelse(words > 0, round((mentions / words) * 1000, 2), 0)
    
    results[[length(results) + 1]] <- data.frame(
      company = company, year = year, quarter = quarter,
      total_mentions = mentions, word_count = words, density = density,
      stringsAsFactors = FALSE
    )
    cat("  → AI:", mentions, "| gęstość:", density, "\n")
  }
  
  if (length(results) == 0) return(NULL)
  df <- bind_rows(results)
  cat("\n=== 10-Q: Wczytano", nrow(df), "plików ===\n")
  
  annual <- df %>%
    filter(quarter %in% c("Q1", "Q2", "Q3")) %>%
    group_by(company, year) %>%
    summarise(
      total_mentions = sum(total_mentions),
      word_count = sum(word_count),
      density = round((sum(total_mentions) / sum(word_count)) * 1000, 2),
      .groups = "drop"
    )
  
  cat("\n--- TABELA 10: Gęstość 10-Q (agregacja roczna Q1-Q3) ---\n")
  table_9 <- annual %>% select(company, year, density) %>%
    pivot_wider(names_from = year, values_from = density, values_fill = 0) %>%
    mutate(
      avg = round((`2022` + `2023` + `2024` + `2025`) / 4, 2),
      change_pp = round(`2025` - `2022`, 2),
      change_pct = round(((`2025` - `2022`) / `2022`) * 100, 1)
    )
  print(table_9)
  
  cat("\n--- TABELA 10.1: Średnia GAMAM (10-Q) ---\n")
  table_10 <- annual %>% group_by(year) %>% summarise(gamam_avg_density = round(mean(density), 2))
  print(table_10)
  
  return(list(raw = df, annual = annual))
}

# =====================================================================
# 6. ANALIZA EARNINGS CALLS
# =====================================================================

analyze_earnings_calls_full <- function(folder_path, results_10k, results_10q_annual) {
  cat("\n", strrep("=", 70), "\n")
  cat("ZAŁĄCZNIK 4 – ANALIZA EARNINGS CALLS (+ presentation/Q&A)\n")
  cat(strrep("=", 70), "\n")
  
  files <- list.files(folder_path, pattern = "\\.txt$", full.names = TRUE)
  results <- list()
  
  for (file in files) {
    name <- basename(file)
    name_clean <- str_replace(name, "\\.txt$", "")
    parts <- str_split(name_clean, "_")[[1]]
    
    company_raw <- parts[1]
    company <- case_when(
      toupper(company_raw) == "ALPHABET" ~ "GOOGL",
      toupper(company_raw) == "AMAZON" ~ "AMZN",
      toupper(company_raw) == "APPLE" ~ "AAPL",
      toupper(company_raw) == "META" ~ "META",
      toupper(company_raw) == "MICROSOFT" ~ "MSFT",
      TRUE ~ NA_character_
    )
    if (is.na(company)) next
    
    fiscal_year <- parts[2]
    fiscal_quarter <- if (length(parts) > 2) parts[3] else NA
    if (is.na(fiscal_quarter)) next
    
    cal <- sync_calendar(fiscal_year, fiscal_quarter, company)
    if (is.na(cal$year) || !cal$year %in% c("2022", "2023", "2024", "2025")) next
    
    cat("Przetwarzam:", company, "FY", fiscal_year, fiscal_quarter, "→ CY", cal$year, cal$quarter, "-", name, "\n")
    
    tekst <- paste(readLines(file, warn = FALSE), collapse = " ")
    if (nchar(tekst) == 0) next
    
    qa_start <- str_locate(tekst, "Questions & Answers:")[1, "start"]
    
    if (!is.na(qa_start)) {
      presentation <- str_sub(tekst, 1, qa_start - 1)
      qa <- str_sub(tekst, qa_start, nchar(tekst))
    } else {
      presentation <- tekst
      qa <- ""
    }
    
    result_caly <- analyze_qualitative(tekst, company, cal$year, "Earnings Call")
    result_caly$quarter <- cal$quarter
    result_caly$part <- "caly"
    result_caly$total_words <- result_caly$words
    
    result_prez <- analyze_qualitative(presentation, company, cal$year, "Earnings Call")
    result_prez$quarter <- cal$quarter
    result_prez$part <- "presentation"
    
    result_qa <- analyze_qualitative(qa, company, cal$year, "Earnings Call")
    result_qa$quarter <- cal$quarter
    result_qa$part <- "qa"
    
    results[[length(results) + 1]] <- result_caly
    results[[length(results) + 1]] <- result_prez
    results[[length(results) + 1]] <- result_qa
    
    cat("  → AI całość:", result_caly$total_ai, "| gęstość:", result_caly$density,
        "| Future:", result_caly$pct_future, "% | Risk:", result_caly$pct_risk, "%\n")
  }
  
  if (length(results) == 0) return(NULL)
  df <- bind_rows(results)
  
  cat("\n--- TABELA 13: Gęstość Earnings Calls (średnia roczna) ---\n")
  table_13 <- df %>% 
    filter(part == "caly") %>%
    group_by(company, year) %>%
    summarise(
      total_ai = sum(AI_Total),
      total_words = sum(total_words),
      srednia_gestosc = round((total_ai / total_words) * 1000, 2),
      .groups = "drop"
    ) %>%
    pivot_wider(
      id_cols = company,
      names_from = year,
      values_from = srednia_gestosc,
      values_fill = 0
    )
  
  print(table_13)
  
  cat("\n--- TABELA 13.1: Średnia GAMAM (Earnings Calls) ---\n")
  table_14 <- df %>% 
    filter(part == "caly") %>%
    group_by(year) %>%
    summarise(
      total_ai = sum(AI_Total),
      total_words = sum(total_words),
      srednia_gestosc_EC = round((total_ai / total_words) * 1000, 2),
      .groups = "drop"
    )
  print(table_14)
  
  cat("\n--- TABELA 13.2: Podział earnings calls na presentation i Q&A ---\n")
  table_15_raw <- df %>% 
    filter(part != "caly") %>%
    group_by(year, part) %>%
    summarise(
      total_words = sum(total_words, na.rm = TRUE),
      total_ai = sum(AI_Total, na.rm = TRUE),
      gestosc = round((total_ai / total_words) * 1000, 2),
      .groups = "drop"
    )
  
  udzial_prez <- table_15_raw %>%
    group_by(year) %>%
    summarise(
      udzial_prezentacji = round(
        total_words[part == "presentation"] / 
          (total_words[part == "presentation"] + total_words[part == "qa"]) * 100, 
        1
      ),
      .groups = "drop"
    )
  
  table_15_wide <- table_15_raw %>%
    select(year, part, gestosc) %>%
    pivot_wider(
      id_cols = year,
      names_from = part,
      values_from = gestosc,
      values_fill = 0
    )
  
  table_15 <- table_15_wide %>%
    left_join(udzial_prez, by = "year") %>%
    select(year, presentation, qa, udzial_prezentacji)
  
  print(table_15)
  
  cat("\n--- TABELA 13.3 PREZENTACJA vs Q&A DLA KAŻDEJ SPÓŁKI W 2025 ROKU ---\n")
  table_15_by_company <- df %>% 
    filter(year == "2025", part != "caly") %>%
    group_by(company, part) %>%
    summarise(
      total_ai = sum(AI_Total),
      total_words = sum(total_words),
      gestosc = round((total_ai / total_words) * 1000, 2),
      .groups = "drop"
    ) %>%
    pivot_wider(
      id_cols = company,
      names_from = part,
      values_from = gestosc,
      values_fill = 0
    )
  print(table_15_by_company)
  
  # === KORELACJA SPEARMANA PRESENTATION vs Q&A ===
  cat("\n--- KORELACJA SPEARMANA: PRESENTATION vs Q&A ---\n")
  
  df_wide_qa <- df %>%
    filter(part %in% c("presentation", "qa")) %>%
    select(company, year, quarter, part, density) %>%
    pivot_wider(names_from = part, values_from = density)
  
  valid_rows <- df_wide_qa %>% filter(!is.na(presentation) & !is.na(qa))
  
  if (nrow(valid_rows) >= 3) {
    cor_test_qa <- cor.test(valid_rows$presentation, valid_rows$qa, method = "spearman", exact = FALSE)
    
    cat(paste("Współczynnik korelacji (rho):", round(cor_test_qa$estimate, 3), "\n"))
    cat(paste("p-value:", round(cor_test_qa$p.value, 4), "\n"))
    
    if (cor_test_qa$p.value < 0.05) {
      cat("✅ Istnieje statystycznie istotny związek między gęstością AI w Prezentacji a w Q&A.\n")
    } else {
      cat("❌ Brak statystycznie istotnego związku między Prezentacją a Q&A.\n")
    }
  } else {
    cat("⚠️ Zbyt mało kompletnych par (Prezentacja + Q&A) do obliczenia korelacji.\n")
  }
  
  # === PORÓWNANIE EC VS 10-K ===
  gest_10k <- results_10k %>% 
    filter(year %in% c("2022", "2023", "2024", "2025")) %>% 
    group_by(year) %>% 
    summarise(gest_10K = round(mean(density), 2), .groups = "drop")
  
  comparison <- table_14 %>% 
    rename(rok = year) %>%
    left_join(gest_10k, by = c("rok" = "year")) %>% 
    mutate(iloraz = round(srednia_gestosc_EC / gest_10K, 1))
  
  cat("\n--- Tabela 14: PORÓWNANIE EARNINGS CALLS VS 10-K ---\n")
  print(comparison)
  
  # === WERYFIKACJA H2 ===
  if (!is.null(results_10q_annual)) {
    h2_ec <- mean(comparison$srednia_gestosc_EC, na.rm = TRUE)
    h2_10k <- mean(comparison$gest_10K, na.rm = TRUE)
    h2_10q <- mean(results_10q_annual$density, na.rm = TRUE)
    cat("\n--- WERYFIKACJA HIPOTEZY H2 ---\n")
    cat(paste("Średnia gęstość EC: ", round(h2_ec, 2), "| 10-K:", round(h2_10k, 2), "| 10-Q:", round(h2_10q, 2), "\n"))
    if(h2_ec > h2_10k && h2_10k > h2_10q) {
      cat("✅ Hipoteza H2 POTWIERDZONA: Earnings Calls > 10-K\n")
    } else {
      cat("❌ Hipoteza H2 NIE POTWIERDZONA\n")
    }
  }
  
  return(list(raw = df, annual = table_13, gamam = table_14, split = table_15))
}

# =====================================================================
# 7. KORELACJE Z R&D I CAPEX
# =====================================================================

analyze_rd_capex_full <- function(results_10k, results_ec = NULL) {
  cat("\n", strrep("=", 70), "\n")
  cat("ZAŁĄCZNIK 5 – KORELACJE Z R&D I CAPEX (H3)\n")
  cat(strrep("=", 70), "\n")
  
  df_rd_capex <- data.frame(
    spolka = c(rep("Alphabet",4), rep("Amazon",4), rep("Apple",4), rep("Meta",4), rep("Microsoft",4)),
    rok = rep(2022:2025, 5),
    rd = c(13.97,14.78,14.09,15.16, 14.24,14.90,13.83,15.14,
           6.66,7.80,8.02,8.30, 30.30,28.53,26.67,28.55, 12.36,12.83,12.04,11.53),
    capex = c(11.13,10.49,15.01,22.70, 12.38,9.17,12.96,18.39,
              2.72,2.86,2.42,3.06, 26.95,20.05,22.65,34.68, 12.05,13.26,18.14,22.91)
  )
  
  df_10k_mapped <- results_10k %>%
    mutate(spolka = case_when(
      company == "GOOGL" ~ "Alphabet",
      company == "AMZN" ~ "Amazon",
      company == "AAPL" ~ "Apple",
      company == "META" ~ "Meta",
      company == "MSFT" ~ "Microsoft"
    ), rok = as.numeric(year))
  
  df <- df_10k_mapped %>% 
    left_join(df_rd_capex, by = c("spolka", "rok")) %>%
    mutate(
      log_ai = log(density + 0.01),
      log_rd = log(rd + 0.01),
      log_capex = log(capex + 0.01)
    )
  
  cat("\n--- TABELA 16.1: KORELACJE SPEARMANA (globalne) ---\n")
  cor_test_rd <- cor.test(df$rd, df$density, method = "spearman", exact = FALSE)
  cor_test_capex <- cor.test(df$capex, df$density, method = "spearman", exact = FALSE)
  cat(paste("R&D vs AI density:   ρ =", round(cor_test_rd$estimate, 2), 
            "p-value =", round(cor_test_rd$p.value, 4), "\n"))
  cat(paste("CAPEX vs AI density: ρ =", round(cor_test_capex$estimate, 2), 
            "p-value =", round(cor_test_capex$p.value, 4), "\n"))
  
  cat("\n--- TABELA 16.2: KORELACJE WEWNĄTRZ SPÓŁEK ---\n")
  for(comp in unique(df$spolka)) {
    dane_comp <- df[df$spolka == comp, ]
    if (nrow(dane_comp) >= 3) {
      cor_rd_comp <- cor(dane_comp$rd, dane_comp$density, method = "spearman", use = "complete.obs")
      cor_capex_comp <- cor(dane_comp$capex, dane_comp$density, method = "spearman", use = "complete.obs")
      cat(paste(comp, ": R&D =", round(cor_rd_comp, 2), "| CAPEX =", round(cor_capex_comp, 2), "\n"))
    }
  }
  
  cat("\n--- TABELA 17: REGRESJA PANELOWA 10-K (Fixed Effects + CR2) ---\n")
  p_df <- pdata.frame(df, index = c("spolka", "rok"))
  
  fe_capex <- plm(density ~ capex, data = p_df, model = "within")
  fe_rd <- plm(density ~ rd, data = p_df, model = "within")
  fe_full <- plm(density ~ capex + rd, data = p_df, model = "within")
  
  cat("\nModel CAPEX (surowy):\n")
  print(clubSandwich::coef_test(fe_capex, vcov = "CR2", cluster = "individual"))
  
  cat("\nModel R&D (surowy):\n")
  print(clubSandwich::coef_test(fe_rd, vcov = "CR2", cluster = "individual"))
  
  cat("\nModel łączny CAPEX + R&D:\n")
  print(clubSandwich::coef_test(fe_full, vcov = "CR2", cluster = "individual"))
  
  fe_log_capex <- plm(log_ai ~ log_capex, data = p_df, model = "within")
  fe_log_rd <- plm(log_ai ~ log_rd, data = p_df, model = "within")
  
  cat("\n--- MODEL CAPEX (log-log, CR2) ---\n")
  print(clubSandwich::coef_test(fe_log_capex, vcov = "CR2", cluster = "individual"))
  
  cat("\n--- MODEL R&D (log-log, CR2) ---\n")
  print(clubSandwich::coef_test(fe_log_rd, vcov = "CR2", cluster = "individual"))
  
  cat("\n--- MODEL CAPEX + EFEKTY CZASOWE (robustness check, CR2) ---\n")
  
  tryCatch({
    fe_capex_time <- plm(density ~ capex + factor(rok), data = p_df, model = "within")
    print(clubSandwich::coef_test(fe_capex_time, vcov = "CR2", cluster = "individual"))
  }, error = function(e) {
    cat("⚠️ Algorytm CR2 nie mógł obliczyć macierzy dla modelu z efektami czasu.\n")
    cat("Powód: Zbyt mała liczba klastrów (N=5) w stosunku do liczby estymowanych parametrów.\n")
  })
  
  # Test Hausmana (FE vs RE)
  re_model <- plm(density ~ capex, data = p_df, model = "random")
  hausman_test <- phtest(fe_capex, re_model)
  
  cat("\n--- TEST HAUSMANA ---\n")
  print(hausman_test)
  cat("Uwaga: Zastosowano model FE niezależnie od wyniku testu Hausmana.\n")
  cat("Uzasadnienie: próba nielosowa (celowy dobór Big Tech) wyklucza\n")
  cat("założenie losowości efektów indywidualnych wymagane przez RE.\n")
  
  # Test F (FE vs Pooled OLS)
  pooled_model <- plm(density ~ capex, data = p_df, model = "pooling")
  f_test <- pFtest(fe_capex, pooled_model)
  
  cat("\n--- TEST F (FE vs POOLED OLS) ---\n")
  print(f_test)
  
  # ===== DIAGNOSTYKA MODELU PANELOWEGO =====
  cat("\n", strrep("=", 70), "\n")
  cat("DIAGNOSTYKA MODELU PANELOWEGO (10-K)\n")
  cat(strrep("=", 70), "\n")
  
  # VIF 
  if (requireNamespace("car", quietly = TRUE)) {
    lm_full <- lm(density ~ capex + rd + factor(spolka) + factor(rok), data = df)
    vif_vals <- car::vif(lm_full)
    cat("\n--- VIF (współliniowość) ---\n")
    print(vif_vals)
    if(any(vif_vals > 5)) cat("⚠️ Uwaga: VIF > 5 – współliniowość\n") else cat("✅ Brak istotnej współliniowości\n")
  }
  
  # Test Breuscha-Pagana (heteroskedastyczność
  bp_test <- lmtest::bptest(fe_full)
  cat("\n--- Test Breuscha-Pagana (heteroskedastyczność) ---\n")
  print(bp_test)
  if(bp_test$p.value < 0.05) cat("✅ Heteroskedastyczność – uzasadnienie dla CR2\n")
  
  # Test Wooldridge'a (autokorelacja w panelu)
  if (requireNamespace("plm", quietly = TRUE)) {
    w_test <- plm::pwartest(fe_full)
    cat("\n--- Test Wooldridge'a (autokorelacja) ---\n")
    print(w_test)
    if(w_test$p.value < 0.05) cat("⚠️ Autokorelacja w panelu\n") else cat("✅ Brak autokorelacji\n")
  }
  
  # Analiza Earnings Calls ===
  if (!is.null(results_ec) && !is.null(results_ec$raw)) {
    df_ec_mapped <- results_ec$raw %>%
      filter(part == "caly") %>%
      mutate(spolka = case_when(
        company == "GOOGL" ~ "Alphabet",
        company == "AMZN" ~ "Amazon",
        company == "AAPL" ~ "Apple",
        company == "META" ~ "Meta",
        company == "MSFT" ~ "Microsoft"
      ), rok = as.numeric(year)) %>%
      group_by(spolka, rok) %>%
      summarise(ec_density = mean(density, na.rm = TRUE), .groups = "drop")
    
    # Optymalizacja przekształceń dla EC
    df_ec_merged <- df_ec_mapped %>% 
      inner_join(df_rd_capex, by = c("spolka", "rok")) %>%
      mutate(
        log_ec = log(ec_density + 0.01),
        log_capex = log(capex + 0.01),
        log_rd = log(rd + 0.01)
      )
    
    cat("\n--- TABELA 16.3: KORELACJE SPEARMANA DLA EARNINGS CALLS ---\n")
    
    get_p <- function(d, col1, col2) {
      d_sub <- d[!is.na(d[[col1]]) & !is.na(d[[col2]]), ]
      if (nrow(d_sub) < 3) return(NA)
      return(round(cor.test(d_sub[[col1]], d_sub[[col2]], method = "spearman", exact = FALSE)$p.value, 4))
    }
    
    tab18 <- data.frame(
      Zakres = c("Globalna", unique(df_ec_merged$spolka)),
      R_vs_EC_rho = sapply(c("Globalna", unique(df_ec_merged$spolka)), function(x) {
        d <- if(x == "Globalna") df_ec_merged else df_ec_merged[df_ec_merged$spolka == x, ]
        if(nrow(d[!is.na(d$rd) & !is.na(d$ec_density), ]) < 3) return(NA)
        round(cor(d$rd, d$ec_density, method = "spearman", use = "complete.obs"), 2)
      }),
      R_vs_EC_p = sapply(c("Globalna", unique(df_ec_merged$spolka)), function(x) {
        d <- if(x == "Globalna") df_ec_merged else df_ec_merged[df_ec_merged$spolka == x, ]
        get_p(d, "rd", "ec_density")
      }),
      CAPEX_vs_EC_rho = sapply(c("Globalna", unique(df_ec_merged$spolka)), function(x) {
        d <- if(x == "Globalna") df_ec_merged else df_ec_merged[df_ec_merged$spolka == x, ]
        if(nrow(d[!is.na(d$capex) & !is.na(d$ec_density), ]) < 3) return(NA)
        round(cor(d$capex, d$ec_density, method = "spearman", use = "complete.obs"), 2)
      }),
      CAPEX_vs_EC_p = sapply(c("Globalna", unique(df_ec_merged$spolka)), function(x) {
        d <- if(x == "Globalna") df_ec_merged else df_ec_merged[df_ec_merged$spolka == x, ]
        get_p(d, "capex", "ec_density")
      })
    )
    print(tab18)
    
    cat("\n--- TABELA 16.4: MODELE REGRESJI PANELOWEJ FE DLA EARNINGS CALLS (CR2) ---\n")
    
    p_df_ec <- pdata.frame(df_ec_merged, index = c("spolka", "rok"))
    
    fe_c_ec <- plm(ec_density ~ capex, data = p_df_ec, model = "within")
    fe_f_ec <- plm(ec_density ~ capex + rd, data = p_df_ec, model = "within")
    fe_rd_ec <- plm(ec_density ~ rd, data = p_df_ec, model = "within")
    
    cat("\n--- MODEL R&D (EC) ---\n")
    print(clubSandwich::coef_test(fe_rd_ec, vcov = "CR2", cluster = "individual"))
    
    fe_log_capex_ec <- plm(log_ec ~ log_capex, data = p_df_ec, model = "within")
    cat("\n--- MODEL LOG-LOG CAPEX (EC) ---\n")
    print(clubSandwich::coef_test(fe_log_capex_ec, vcov = "CR2", cluster = "individual"))
    
    fe_log_rd_ec <- plm(log_ec ~ log_rd, data = p_df_ec, model = "within")
    cat("\n--- MODEL LOG-LOG R&D (EC) ---\n")
    print(clubSandwich::coef_test(fe_log_rd_ec, vcov = "CR2", cluster = "individual"))
    
    cat("\n--- MODEL CAPEX + CZAS (EC) ---\n")
    tryCatch({
      fe_capex_time_ec <- plm(ec_density ~ capex + factor(rok), data = p_df_ec, model = "within")
      print(clubSandwich::coef_test(fe_capex_time_ec, vcov = "CR2", cluster = "individual"))
    }, error = function(e) {
      cat("⚠️ Ominięto CR2 dla modelu z czasem ze względu na brak stopni swobody.\n")
    })
    
    tab19 <- data.frame(
      Model = c("CAPEX (EC)", "CAPEX + R&D (EC)"),
      Wsp_CAPEX = c(round(coef(fe_c_ec)["capex"], 4), round(coef(fe_f_ec)["capex"], 4)),
      P_val_CR2 = c(
        round(clubSandwich::coef_test(fe_c_ec, vcov = "CR2", cluster = "individual")["capex", "p_Satt"], 4),
        round(clubSandwich::coef_test(fe_f_ec, vcov = "CR2", cluster = "individual")["capex", "p_Satt"], 4)
      ),
      R2_Adj = c(round(summary(fe_c_ec)$r.squared[1], 3), round(summary(fe_f_ec)$r.squared[1], 3))
    )
    print(tab19)
  }
  
  res_cr2_capex <- clubSandwich::coef_test(fe_capex, vcov = "CR2", cluster = "individual")
  p_val_capex <- res_cr2_capex["capex", "p_Satt"]
  coef_capex <- coef(fe_capex)["capex"]
  
  res_cr2_rd <- clubSandwich::coef_test(fe_rd, vcov = "CR2", cluster = "individual")
  p_val_rd <- res_cr2_rd["rd", "p_Satt"]
  coef_rd <- coef(fe_rd)["rd"]
  
  cat("\n", strrep("=", 70), "\n")
  cat("WERYFIKACJA WYNIKÓW DLA NAKŁADÓW NA INNOWACJE (estymator CR2)\n")
  cat(strrep("=", 70), "\n")
  
  cat("--- Wpływ CAPEX na gęstość AI ---\n")
  if (p_val_capex < 0.05 && coef_capex > 0) {
    cat(sprintf("✅ ISTOTNY POZYTYWNY wpływ (beta = %.4f | p-value = %.4f)\n", coef_capex, p_val_capex))
  } else if (p_val_capex < 0.05 && coef_capex < 0) {
    cat(sprintf("❌ ISTOTNY NEGATYWNY wpływ (beta = %.4f | p-value = %.4f)\n", coef_capex, p_val_capex))
  } else {
    cat(sprintf("❌ BRAK ISTOTNEGO WPŁYWU statystycznie (beta = %.4f | p-value = %.4f)\n", coef_capex, p_val_capex))
  }
  
  cat("\n--- Wpływ R&D na gęstość AI ---\n")
  if (p_val_rd < 0.05 && coef_rd > 0) {
    cat(sprintf("✅ ISTOTNY POZYTYWNY wpływ (beta = %.4f | p-value = %.4f)\n", coef_rd, p_val_rd))
  } else if (p_val_rd < 0.05 && coef_rd < 0) {
    cat(sprintf("❌ ISTOTNY NEGATYWNY wpływ (beta = %.4f | p-value = %.4f)\n", coef_rd, p_val_rd))
  } else {
    cat(sprintf("❌ BRAK ISTOTNEGO WPŁYWU statystycznie (beta = %.4f | p-value = %.4f)\n", coef_rd, p_val_rd))
  }
  
  cat("\n")
  
  fe_capex <<- fe_capex
  fe_rd <<- fe_rd
  fe_full <<- fe_full
  p_val_capex <<- p_val_capex
  coef_capex <<- coef_capex
  p_val_rd <<- p_val_rd
  coef_rd <<- coef_rd
  
  return(df)
}

# =====================================================================
# 8. ANALIZA JAKOŚCIOWA
# =====================================================================

qualitative_summary_full <- function(results_10k, results_ec) {
  cat("\n", strrep("=", 70), "\n")
  cat("ZAŁĄCZNIK 6 – ANALIZA JAKOŚCIOWA (Future/Risk, General/Specific)\n")
  cat(strrep("=", 70), "\n")
  
  all_results <- bind_rows(
    results_10k,
    results_ec$raw %>% filter(part == "caly")
  )
  
  cat("\n--- TABELA 22: ŚREDNIA DLA GRUPY GAMAM (ważona) ---\n")
  summary_weighted <- all_results %>% group_by(doc_type) %>%
    summarise(
      Pct_General = round(sum(AI_General_Count, na.rm = TRUE) / sum(AI_Total, na.rm = TRUE) * 100, 1),
      Pct_Specific = round(sum(AI_Specific_Count, na.rm = TRUE) / sum(AI_Total, na.rm = TRUE) * 100, 1),
      Pct_Future = round(sum(Future_Count, na.rm = TRUE) / sum(AI_Sentences_Count, na.rm = TRUE) * 100, 1),
      Pct_Risk = round(sum(Risk_Count, na.rm = TRUE) / sum(AI_Sentences_Count, na.rm = TRUE) * 100, 1)
    )
  print(summary_weighted)
  
  cat("\n--- TABELA 22.1: DLA KAŻDEJ SPÓŁKI (ważona) ---\n")
  by_company_weighted <- all_results %>% group_by(company, doc_type) %>%
    summarise(
      Pct_General = round(sum(AI_General_Count, na.rm = TRUE) / sum(AI_Total, na.rm = TRUE) * 100, 1),
      Pct_Specific = round(sum(AI_Specific_Count, na.rm = TRUE) / sum(AI_Total, na.rm = TRUE) * 100, 1),
      Pct_Future = round(sum(Future_Count, na.rm = TRUE) / sum(AI_Sentences_Count, na.rm = TRUE) * 100, 1),
      Pct_Risk = round(sum(Risk_Count, na.rm = TRUE) / sum(AI_Sentences_Count, na.rm = TRUE) * 100, 1),
      .groups = "drop"
    ) %>% arrange(company, doc_type)
  
  print(by_company_weighted, n = Inf)
  
  return(all_results)
}

# =====================================================================
# 9. EVENT STUDY
# =====================================================================

calculate_car <- function(event_date, firm, prices_wide, start_shift = -1, end_shift = 1) {
  if (!firm %in% colnames(prices_wide)) return(NA)
  
  idx_pub <- which(prices_wide$data >= event_date)
  if (length(idx_pub) == 0) return(NA)
  idx_pub <- min(idx_pub)
  
  if (abs(prices_wide$data[idx_pub] - event_date) > 3) return(NA)
  
  event_idx <- idx_pub + 1
  if (event_idx < 2 || event_idx > nrow(prices_wide)) return(NA)
  
  est_start <- max(1, idx_pub - 130)
  est_end <- idx_pub - 11
  if (est_end <= est_start || est_end > nrow(prices_wide)) return(NA)
  
  est_data <- prices_wide[est_start:est_end, ]
  firm_returns <- diff(log(est_data[[firm]]))
  market_returns <- diff(log(est_data$SPX))
  valid <- !is.na(firm_returns) & !is.na(market_returns)
  if (sum(valid) < 10) return(NA)
  
  model <- lm(firm_returns[valid] ~ market_returns[valid])
  alpha <- coef(model)[1]
  beta <- coef(model)[2]
  
  ev_start_idx <- max(2, event_idx + start_shift)
  ev_end_idx <- min(nrow(prices_wide), event_idx + end_shift)
  if (ev_start_idx >= ev_end_idx) return(NA)
  
  ev_data <- prices_wide[(ev_start_idx - 1):ev_end_idx, ]
  ar <- c()
  for (i in 2:nrow(ev_data)) {
    firm_ret <- log(ev_data[[firm]][i] / ev_data[[firm]][i-1])
    market_ret <- log(ev_data$SPX[i] / ev_data$SPX[i-1])
    if (!is.na(firm_ret) && !is.na(market_ret)) {
      ar <- c(ar, firm_ret - (alpha + beta * market_ret))
    }
  }
  return(sum(ar, na.rm = TRUE))
}


calculate_car_t0 <- function(event_date, firm, prices_wide) {
  if (!firm %in% colnames(prices_wide)) return(NA)
  
  idx_pub <- which(prices_wide$data >= event_date)
  if (length(idx_pub) == 0) return(NA)
  idx_pub <- min(idx_pub)
  
  if (abs(prices_wide$data[idx_pub] - event_date) > 3) return(NA)
  
  event_idx <- idx_pub + 1
  if (event_idx < 2 || event_idx > nrow(prices_wide)) return(NA)
  
  est_start <- max(1, idx_pub - 130)
  est_end <- idx_pub - 11
  if (est_end <= est_start || est_end > nrow(prices_wide)) return(NA)
  
  est_data <- prices_wide[est_start:est_end, ]
  firm_returns <- diff(log(est_data[[firm]]))
  market_returns <- diff(log(est_data$SPX))
  valid <- !is.na(firm_returns) & !is.na(market_returns)
  if (sum(valid) < 10) return(NA)
  
  model <- lm(firm_returns[valid] ~ market_returns[valid])
  alpha <- coef(model)[1]
  beta <- coef(model)[2]
  
  firm_ret <- log(prices_wide[[firm]][event_idx] / prices_wide[[firm]][event_idx - 1])
  market_ret <- log(prices_wide$SPX[event_idx] / prices_wide$SPX[event_idx - 1])
  if (!is.na(firm_ret) && !is.na(market_ret)) {
    return(firm_ret - (alpha + beta * market_ret))
  }
  return(NA)
}

calculate_sar <- function(event_date, firm, prices_wide, start_shift = -1, end_shift = 1) {
  if (!firm %in% colnames(prices_wide)) return(NA)
  
  idx_pub <- which(prices_wide$data >= event_date)
  if (length(idx_pub) == 0) return(NA)
  idx_pub <- min(idx_pub)
  
  if (abs(prices_wide$data[idx_pub] - event_date) > 3) return(NA)
  
  event_idx <- idx_pub + 1
  if (event_idx < 2 || event_idx > nrow(prices_wide)) return(NA)
  
  est_start <- max(1, idx_pub - 130)
  est_end <- idx_pub - 11
  if (est_end <= est_start || est_end > nrow(prices_wide)) return(NA)
  
  est_data <- prices_wide[est_start:est_end, ]
  firm_returns <- diff(log(est_data[[firm]]))
  market_returns <- diff(log(est_data$SPX))
  valid <- !is.na(firm_returns) & !is.na(market_returns)
  if (sum(valid) < 10) return(NA)
  
  model <- lm(firm_returns[valid] ~ market_returns[valid])
  alpha <- coef(model)[1]
  beta <- coef(model)[2]
  sigma_est <- summary(model)$sigma
  T_est <- length(firm_returns[valid])
  m_avg <- mean(market_returns[valid])
  m_sum_sq <- sum((market_returns[valid] - m_avg)^2)
  
  ev_start_idx <- max(2, event_idx + start_shift)
  ev_end_idx <- min(nrow(prices_wide), event_idx + end_shift)
  if (ev_start_idx >= ev_end_idx) return(NA)
  
  ev_data <- prices_wide[(ev_start_idx - 1):ev_end_idx, ]
  sar_vec <- c()
  for (i in 2:nrow(ev_data)) {
    firm_ret <- log(ev_data[[firm]][i] / ev_data[[firm]][i-1])
    market_ret <- log(ev_data$SPX[i] / ev_data$SPX[i-1])
    if (!is.na(firm_ret) && !is.na(market_ret)) {
      ar_it <- firm_ret - (alpha + beta * market_ret)
      C_it <- sqrt(1 + 1/T_est + ((market_ret - m_avg)^2 / m_sum_sq))
      sar_it <- ar_it / (sigma_est * C_it)
      sar_vec <- c(sar_vec, sar_it)
    }
  }
  return(sum(sar_vec, na.rm = TRUE))
}

calculate_volume_change <- function(event_row, volumes_wide, ev_start = -1, ev_end = 1, shift = 1) {
  event_date <- as.Date(event_row$event_date)
  firm <- event_row$spolka
  vol_col <- firm
  
  if (!vol_col %in% colnames(volumes_wide)) return(NA)
  idx_pub <- which(volumes_wide$data >= event_date)
  if (length(idx_pub) == 0) return(NA)
  idx_pub <- min(idx_pub)
  
  if (abs(volumes_wide$data[idx_pub] - event_date) > 3) return(NA)
  
  event_idx <- idx_pub + shift
  if (event_idx < 1 || event_idx > nrow(volumes_wide)) return(NA)
  
  base_start <- max(1, idx_pub - 30)
  base_end <- idx_pub - 11
  if (base_end <= base_start || base_end > nrow(volumes_wide)) return(NA)
  
  base_vol <- mean(volumes_wide[[vol_col]][base_start:base_end], na.rm = TRUE)
  if (base_vol == 0 || is.na(base_vol)) return(NA)
  
  ev_start_idx <- max(1, event_idx + ev_start)
  ev_end_idx <- min(nrow(volumes_wide), event_idx + ev_end)
  if (ev_start_idx > ev_end_idx) return(NA)
  
  ev_vol <- mean(volumes_wide[[vol_col]][ev_start_idx:ev_end_idx], na.rm = TRUE)
  
  return((ev_vol - base_vol) / base_vol * 100)
}

load_price_data <- function(folder_prices) {
  spolki <- c("AAPL", "MSFT", "GOOGL", "AMZN", "META", "SPX")
  ceny <- list()
  for (s in spolki) {
    csv_file <- file.path(folder_prices, paste0(s, "_US.csv"))
    if (file.exists(csv_file)) {
      d <- read.csv(csv_file)
      colnames(d) <- c("data", "open", "high", "low", "close", "volume")
      d$data <- as.Date(d$data)
      ceny[[s]] <- d[, c("data", "close", "volume")]
    }
  }
  prices_wide <- ceny[["SPX"]] %>% select(data, close) %>% rename(SPX = close)
  for (s in spolki[spolki != "SPX"]) {
    if (!is.null(ceny[[s]])) {
      prices_wide <- prices_wide %>% left_join(ceny[[s]] %>% select(data, close) %>% rename(!!s := close), by = "data")
    }
  }
  volumes_wide <- data.frame(data = prices_wide$data)
  for (s in spolki[spolki != "SPX"]) {
    if (!is.null(ceny[[s]])) {
      volumes_wide <- volumes_wide %>% left_join(ceny[[s]] %>% select(data, volume) %>% rename(!!s := volume), by = "data")
    }
  }
  return(list(prices = prices_wide, volumes = volumes_wide))
}

# === Testy alternatywne dla Załącznika 7 ===
run_alternative_tests <- function(df_all) {
  cat("\n", strrep("=", 70), "\n")
  cat("ZAŁĄCZNIK 7.1 – ALTERNATYWNE TESTY STATYSTYCZNE DLA HIPOTEZY H4\n")
  cat(strrep("=", 70), "\n")
  
  # Sprawdź czy df_all istnieje
  if (!exists("df_all")) {
    cat("❌ Brak df_all - najpierw uruchom event study\n")
    return(NULL)
  }
  
  # ===== 1. PRZYGOTOWANIE DANYCH =====
  ec_data <- df_all %>% filter(typ == "Earnings Call",
                               year_calendar %in% c("2022","2023","2024","2025"),
                               !is.na(CAR_m1_1))
  
  cat("\n=== LICZBA OBSERWACJI ===\n")
  cat("EC:", nrow(ec_data), "\n")
  cat("HIGH:", sum(ec_data$ai_intensity == "HIGH"), "\n")
  cat("LOW:", sum(ec_data$ai_intensity == "LOW"), "\n\n")
  
  # ===== 2. TEST PERMUTACYJNY (bez założeń) =====
  cat("=== TEST PERMUTACYJNY ===\n")
  
  obs_diff <- mean(ec_data$CAR_m1_1[ec_data$ai_intensity == "HIGH"]) - 
    mean(ec_data$CAR_m1_1[ec_data$ai_intensity == "LOW"])
  
  set.seed(123)
  n_perm <- 10000
  perm_diffs <- replicate(n_perm, {
    perm_intensity <- sample(ec_data$ai_intensity)
    mean(ec_data$CAR_m1_1[perm_intensity == "HIGH"]) - 
      mean(ec_data$CAR_m1_1[perm_intensity == "LOW"])
  })
  
  p_perm <- mean(abs(perm_diffs) >= abs(obs_diff))
  cat("Obserwowana różnica:", round(obs_diff, 6), "\n")
  cat("p-value (permutacyjny):", p_perm, "\n")
  if(p_perm < 0.05) cat("✅ Istotne\n") else cat("❌ Nieistotne\n\n")
  
  # ===== 3. TEST BAYESA (Bayes Factor) =====
  cat("=== Bayes Factor ===\n")
  
  if (requireNamespace("BayesFactor", quietly = TRUE)) {
    library(BayesFactor)
    bf_result <- ttestBF(formula = CAR_m1_1 ~ ai_intensity, data = ec_data)
    bf <- extractBF(bf_result)$bf
    cat("Bayes Factor:", round(bf, 3), "\n")
    if(bf > 3) {
      cat("✅ Dowód za różnicą (istotne)\n")
    } else if(bf < 1/3) {
      cat("✅ Dowód za BRAKIEM różnicy\n")
    } else {
      cat("❌ Dowód niejednoznaczny\n")
    }
    cat("Interpretacja: BF > 3 = dowód za H1, BF < 1/3 = dowód za brakiem H1\n\n")
  } else {
    cat("⚠️ Pakiet BayesFactor nie jest zainstalowany\n")
    cat("Pomijam ten test\n\n")
  }
  
  # ===== 4. REGRESJA KWANTYLOWA (odporna na outliery) =====
  cat("=== REGRESJA KWANTYLOWA (mediana) ===\n")
  
  if (requireNamespace("quantreg", quietly = TRUE)) {
    library(quantreg)
    
    # Przygotuj dane
    qr_data <- ec_data
    qr_data$ai_binary <- ifelse(qr_data$ai_intensity == "HIGH", 1, 0)
    qr_data$year_num <- as.numeric(qr_data$year_calendar)
    
    # Model z binarną zmienną
    qr_model <- suppressWarnings(rq(CAR_m1_1 ~ ai_binary + year_num, data = qr_data, tau = 0.5))
    qr_sum <- summary(qr_model, se = "boot", R = 1000)
    
    # Sprawdź współczynnik dla ai_binary
    if ("ai_binary" %in% rownames(qr_sum$coefficients)) {
      qr_coef <- qr_sum$coefficients["ai_binary", 1]
      qr_p <- qr_sum$coefficients["ai_binary", 4]
      cat("Różnica median (HIGH vs LOW):", round(qr_coef, 6), "\n")
      cat("p-value:", round(qr_p, 4), "\n")
      if(qr_p < 0.05) cat("✅ Istotne\n") else cat("❌ Nieistotne\n\n")
    } else {
      cat("Brak współczynnika w modelu\n")
      cat("Dostępne współczynniki:", paste(rownames(qr_sum$coefficients), collapse=", "), "\n\n")
    }
  } else {
    cat("⚠️ Pakiet quantreg nie jest zainstalowany\n")
    cat("Pomijam ten test\n\n")
  }
  
  # ===== 5. BOOTSTRAPOWY PRZEDZIAŁ UFNOŚCI =====
  cat("=== BOOTSTRAPOWY PRZEDZIAŁ UFNOŚCI ===\n")
  
  set.seed(123)
  n_boot <- 5000
  boot_diffs <- replicate(n_boot, {
    boot_idx <- sample(1:nrow(ec_data), replace = TRUE)
    boot_df <- ec_data[boot_idx, ]
    mean(boot_df$CAR_m1_1[boot_df$ai_intensity == "HIGH"]) - 
      mean(boot_df$CAR_m1_1[boot_df$ai_intensity == "LOW"])
  })
  
  ci_boot <- quantile(boot_diffs, c(0.025, 0.975))
  cat("95% przedział ufności (bootstrap): [", round(ci_boot[1], 6), ", ", round(ci_boot[2], 6), "]\n")
  if(ci_boot[1] > 0 || ci_boot[2] < 0) {
    cat("✅ Przedział nie zawiera 0 – istotne\n\n")
  } else {
    cat("❌ Przedział zawiera 0 – nieistotne\n\n")
  }
  
  # ===== 5. ANALIZA ZMIANY INTENSYWNOŚCI AI (delta_density) =====
  cat("=== ANALIZA ZMIANY INTENSYWNOŚCI AI (delta_density) ===\n")
  cat("Hipoteza: rynek reaguje na WZROST ujawnień AI, nie na ich poziom\n\n")
  
  p_matched <- NA
  t_test_matched_result <- NULL
  
  # Przygotowanie danych – tylko Earnings Calls
  delta_data <- df_all %>%
    filter(typ == "Earnings Call",
           year_calendar %in% c("2022", "2023", "2024", "2025"),
           !is.na(CAR_m1_1), !is.na(density)) %>%
    distinct(spolka, event_date, .keep_all = TRUE) %>%
    arrange(spolka, event_date) %>%
    group_by(spolka) %>%
    mutate(
      density_lag   = dplyr::lag(density),
      delta_density = density - density_lag
    ) %>%
    ungroup() %>%
    filter(!is.na(delta_density)) %>%
    mutate(period_id = as.numeric(factor(event_date)))  # unikalny ID okresu dla pdata.frame
  
  cat("Obserwacji po usunięciu pierwszego okresu:", nrow(delta_data), "\n")
  cat("Firm:", length(unique(delta_data$spolka)), "\n\n")
  
  # --- Rozkład kierunku zmian (informacyjnie) ---
  delta_data <- delta_data %>%
    mutate(delta_direction = ifelse(delta_density > 0, "WZROST", "SPADEK"))
  
  cat("--- Rozkład kierunku zmian ---\n")
  print(table(delta_data$delta_direction, delta_data$year_calendar))
  cat("\n")
  
  # --- MODEL 1: FE + CR2, delta_density ciągła ---
  cat("--- MODEL 1: CAR ~ delta_density (FE + CR2) ---\n")
  p_delta <- pdata.frame(delta_data, index = c("spolka", "period_id"))
  
  fe_delta_1 <- plm(CAR_m1_1 ~ delta_density,
                    data  = p_delta,
                    model = "within")
  
  cr2_delta_1 <- clubSandwich::coef_test(fe_delta_1, vcov = "CR2", cluster = "individual")
  cat("Współczynnik delta_density:", round(cr2_delta_1["delta_density", "beta"], 6), "\n")
  cat("p-value (Satterthwaite):",    round(cr2_delta_1["delta_density", "p_Satt"], 4), "\n")
  if (cr2_delta_1["delta_density", "p_Satt"] < 0.05) {
    cat("✅ Istotne – rynek reaguje na zmianę intensywności AI\n\n")
  } else {
    cat("❌ Nieistotne\n\n")
  }
  
  # --- MODEL 2: FE + CR2, delta_density + eps_surprise ---
  cat("--- MODEL 2: CAR ~ delta_density + eps_surprise (FE + CR2) ---\n")
  fe_delta_2 <- plm(CAR_m1_1 ~ delta_density + eps_surprise,
                    data  = p_delta,
                    model = "within")
  
  cr2_delta_2 <- clubSandwich::coef_test(fe_delta_2, vcov = "CR2", cluster = "individual")
  cat("Współczynnik delta_density:", round(cr2_delta_2["delta_density", "beta"], 6), "\n")
  cat("p-value (Satterthwaite):",    round(cr2_delta_2["delta_density", "p_Satt"], 4), "\n")
  cat("Współczynnik eps_surprise:",  round(cr2_delta_2["eps_surprise", "beta"], 6), "\n")
  cat("p-value eps_surprise:",       round(cr2_delta_2["eps_surprise", "p_Satt"], 4), "\n")
  if (cr2_delta_2["delta_density", "p_Satt"] < 0.05) {
    cat("✅ Istotne po kontroli EPS surprise\n\n")
  } else {
    cat("❌ Nieistotne po kontroli EPS surprise\n\n")
  }
  
  # --- Tabela podsumowująca modele ---
  cat("--- Podsumowanie modeli FE (delta_density) ---\n")
  summary_delta <- data.frame(
    Model        = c("M1: CAR ~ delta_density",
                     "M2: CAR ~ delta_density + EPS"),
    Beta_delta   = round(c(cr2_delta_1["delta_density", "beta"],
                           cr2_delta_2["delta_density", "beta"]), 6),
    SE           = round(c(cr2_delta_1["delta_density", "SE"],
                           cr2_delta_2["delta_density", "SE"]), 6),
    p_Satt       = round(c(cr2_delta_1["delta_density", "p_Satt"],
                           cr2_delta_2["delta_density", "p_Satt"]), 4),
    Istotne      = ifelse(c(cr2_delta_1["delta_density", "p_Satt"],
                            cr2_delta_2["delta_density", "p_Satt"]) < 0.05, "✅", "❌")
  )
  print(summary_delta)
  
  # --- Średni CAR według kierunku zmiany i roku (opisowo) ---
  cat("\n--- Średni CAR według kierunku zmiany i roku ---\n")
  delta_summary <- delta_data %>%
    group_by(year_calendar, delta_direction) %>%
    summarise(
      mean_CAR = round(mean(CAR_m1_1, na.rm = TRUE), 5),
      n        = n(),
      .groups  = "drop"
    ) %>%
    pivot_wider(names_from  = delta_direction,
                values_from = c(mean_CAR, n),
                values_fill = list(mean_CAR = NA, n = 0))
  print(delta_summary)
  
  # Zapisz p-value do podsumowania
  p_matched <- cr2_delta_2["delta_density", "p_Satt"]
  
  # ===== PODSUMOWANIE =====
  cat("\n", strrep("=", 70), "\n")
  cat("PODSUMOWANIE ALTERNATYWNYCH TESTÓW\n")
  cat(strrep("=", 70), "\n")
  
  # Test permutacyjny
  cat("Test permutacyjny: p =", round(p_perm, 4), if(p_perm < 0.05) " ✅" else " ❌", "\n")
  
  # Bayes Factor
  if (exists("bf")) {
    cat("Bayes Factor: BF =", round(bf, 3),
        if(bf > 3) " ✅ (za H1)" else if(bf < 1/3) " ✅ (za brakiem H1)" else " ❌ (niejednoznaczny)", "\n")
  }
  
  # Regresja kwantylowa
  if (exists("qr_p")) {
    cat("Regresja kwantylowa: p =", round(qr_p, 4), if(qr_p < 0.05) " ✅" else " ❌", "\n")
  }
  
  # Bootstrap
  cat("Bootstrap CI: ", if(ci_boot[1] > 0 || ci_boot[2] < 0) "✅ (nie zawiera 0)" else "❌ (zawiera 0)", "\n")
  
  #delta intensity
  cat("Analiza delta_density:",
      if (!is.na(p_matched)) {
        paste0("p = ", round(p_matched, 4), if (p_matched < 0.05) " ✅" else " ❌")
      } else "❌ brak wyników", "\n")
  
  # Zwróć wyniki
  return(list(
    obs_diff = obs_diff,
    p_perm = p_perm,
    bf = if(exists("bf")) bf else NA,
    qr_p = if(exists("qr_p")) qr_p else NA,
    ci_boot = ci_boot
  ))
}

analyze_event_study <- function(folder_7, ai_terms_sorted) {
  cat("\n", strrep("=", 70), "\n")
  cat("ZAŁĄCZNIK 7 – EVENT STUDY (CAR, BMP, wolumen, H4, T+0, bez 2022)\n")
  cat("UWAGA: Czytanie plików bezpośrednio z folderu:", folder_7, "\n")
  cat(strrep("=", 70), "\n")
  
  pliki <- list.files(folder_7, pattern = "\\.pdf$|\\.txt$", full.names = TRUE, recursive = FALSE)
  cat("Znaleziono plików:", length(pliki), "\n")
  wyniki <- list()
  
  # LICZNIK POSTĘPU
  total_files <- length(pliki)
  processed_files <- 0
  
  for (plik in pliki) {
    processed_files <- processed_files + 1
    nazwa <- basename(plik)
    
    # 1. Ekstrakcja danych (Regex)
    if (grepl("10-K", nazwa, ignore.case = TRUE)) { typ <- "10-K"
    } else if (grepl("10-Q", nazwa, ignore.case = TRUE)) { typ <- "10-Q"
    } else if (grepl("earnings", nazwa, ignore.case = TRUE) || grepl("Earnings", nazwa)) { typ <- "Earnings Call"
    } else { next }
    
    if (grepl("Alphabet|GOOGL", nazwa, ignore.case = TRUE)) { spolka <- "GOOGL"
    } else if (grepl("Amazon|AMZN", nazwa, ignore.case = TRUE)) { spolka <- "AMZN"
    } else if (grepl("Apple|AAPL", nazwa, ignore.case = TRUE)) { spolka <- "AAPL"
    } else if (grepl("Meta|META|Facebook", nazwa, ignore.case = TRUE)) { spolka <- "META"
    } else if (grepl("Microsoft|MSFT", nazwa, ignore.case = TRUE)) { spolka <- "MSFT"
    } else { next }
    
    rok <- str_extract(nazwa, "202[0-6]")
    if (is.na(rok)) next
    
    kwartal <- str_extract(nazwa, "Q[1-4]")
    if (is.na(kwartal)) {
      kwartal <- str_extract(nazwa, "(?<=10-Q)[1-4]")
      if (!is.na(kwartal)) kwartal <- paste0("Q", kwartal)
    }
    if (is.na(kwartal)) kwartal <- "unknown"
    
    # 2. Wczytywanie tekstu (PDF / TXT)
    if (grepl("\\.pdf$", nazwa, ignore.case = TRUE)) {
      text <- tryCatch({
        pages <- pdftools::pdf_text(plik)
        pages <- pages[nchar(pages) > 20]
        text <- paste(pages, collapse = " ")
        text <- gsub("([a-zA-Z])-\\s+([a-zA-Z])", "\\1\\2", text)
        text <- gsub("([a-zA-Z])-\\n+([a-zA-Z])", "\\1\\2", text)
        text <- gsub("[\r\n\t]", " ", text)
        text <- gsub("\\s+", " ", text)
        text <- iconv(text, from = "UTF-8", to = "ASCII", sub = " ")
        clean_text(text)
      }, error = function(e) { "" })
    } else {
      text <- tryCatch({
        text <- paste(readLines(plik, warn = FALSE), collapse = " ")
        clean_text(text)
      }, error = function(e) { "" })
    }
    
    if (nchar(text) < 50) next
    
    # 3. Obliczenia
    mentions <- count_terms(text, ai_terms_sorted)
    words <- count_words(text)
    density <- ifelse(words > 0, round((mentions / words) * 1000, 2), 0)
    
    # 4. WYŚWIETLANIE POSTĘPU (Teraz zmienne 'typ', 'rok' i 'density' już istnieją!)
    cat(sprintf("\r[%d/%d] %s | %s %s %s | AI: %d (%.2f)", 
                processed_files, total_files, spolka, typ, rok, kwartal, mentions, density), flush = TRUE)
    flush.console()
    
    wyniki[[length(wyniki) + 1]] <- data.frame(
      plik = nazwa, spolka = spolka, typ = typ,
      rok = rok, kwartal = kwartal, density = density,
      stringsAsFactors = FALSE
    )
  }
  cat("\n")
  
  df_documents <- bind_rows(wyniki)
  cat("\n=== Wczytano dokumentów:", nrow(df_documents), "===\n")
  
  df_documents <- df_documents %>%
    mutate(
      kwartal = ifelse(typ == "10-K", "Q4", kwartal),
      kwartal = ifelse(kwartal == "unknown", NA, kwartal),
      rok = as.character(rok)
    ) %>%
    filter(!is.na(kwartal))
  
  excel_file <- file.path(folder_7, "mag_tabele_i_wykresy.xlsx")
  if (!file.exists(excel_file)) {
    cat("⚠️ Brak pliku Excel z datami zdarzeń – pomijam event study\n")
    return(NULL)
  }
  
  events <- read_excel(excel_file) %>%
    mutate(event_date = as.Date(event_date, format = "%d.%m.%Y"),
           firm_symbol = str_remove(firm_symbol, "\\.US$"),
           group = case_when(
             grepl("Earnings", group, ignore.case = TRUE) ~ "Earnings Call",
             TRUE ~ group
           ),
           year_fiscal = as.character(year),
           quarter_fiscal = as.character(quarter),
           eps_surprise = as.numeric(eps_surprise))
  assign("df_documents", df_documents, envir = .GlobalEnv)
  assign("events", events, envir = .GlobalEnv)
  df_all <- df_documents %>%
    inner_join(events, by = c("spolka" = "firm_symbol", "typ" = "group", 
                              "rok" = "year_fiscal", "kwartal" = "quarter_fiscal")) %>%
    mutate(year_calendar = as.character(year(ymd(event_date))))
  
  cat("Połączono zdarzeń:", nrow(df_all), "\n")
  if (nrow(df_all) == 0) return(NULL)
  
  price_vol <- load_price_data(folder_7)
  prices_wide <- price_vol$prices
  volumes_wide <- price_vol$volumes
  
  windows <- list(
    list(name = "m1_1", start = -1, end = 1, label = "[-1,+1]"),
    list(name = "m2_2", start = -2, end = 2, label = "[-2,+2]"),
    list(name = "m3_3", start = -3, end = 3, label = "[-3,+3]"),
    list(name = "m5_5", start = -5, end = 5, label = "[-5,+5]")
  )
  
  cat("\n", strrep("-", 70), "\n")
  cat("OBLICZAM CAR DLA RÓŻNYCH OKIEN\n")
  cat(strrep("-", 70), "\n")
  
  total_events <- nrow(df_all)
  bar_width <- 40  # Szerokość paska postępu
  
  for (w in windows) {
    col_name <- paste0("CAR_", w$name)
    cat(sprintf("\n→ Okno %s (%d zdarzeń)\n", w$label, total_events), flush = TRUE)
    
    # Inicjalizacja paska postępu
    cat("  [", paste(rep(" ", bar_width), collapse = ""), "] 0%", sep = "", flush = TRUE)
    
    df_all[[col_name]] <- sapply(1:nrow(df_all), function(i) {
      if (i %% max(1, round(total_events/20)) == 0 || i == total_events) {
        pct <- round(i/total_events * 100)
        filled <- round(pct/100 * bar_width)
        
        cat(sprintf("\r  [%s%s] %3d%%", 
                    paste(rep("=", filled), collapse = ""),
                    paste(rep(" ", bar_width - filled), collapse = ""),
                    pct), flush = TRUE)
        flush.console()
      }
      
      calculate_car(df_all$event_date[i], df_all$spolka[i], prices_wide, w$start, w$end)
    })
    
    cat("\n", flush = TRUE)
    completed <- sum(!is.na(df_all[[col_name]]))
    cat(sprintf("  ✅ %d/%d obliczeń CAR\n", completed, total_events), flush = TRUE)
  }
  
  df_all$CAR <- df_all$CAR_m1_1
  
  # === PODZIAŁ NA GRUPY HIGH/LOW ===
  medians <- df_all %>% group_by(typ) %>% summarise(med = median(density, na.rm = TRUE))
  df_all <- df_all %>% left_join(medians, by = "typ") %>%
    mutate(ai_intensity = ifelse(density > med, "HIGH", "LOW")) %>%
    select(-med)
  
  cat("\n--- MEDIANY GĘSTOŚCI AI (podział HIGH/LOW) ---\n")
  for(doc_type in c("10-K", "10-Q", "Earnings Call")) {
    med_val <- medians %>% filter(typ == doc_type) %>% pull(med)
    cat(paste0(doc_type, ": ", round(med_val, 4), "\n"))
  }
  cat("\n")
  
  # === TABELA 23: CAAR (Średnie CAR) ===
  cat("\n--- TABELA 23: CAAR (Średnie CAR) ---\n")
  for(doc_type in c("10-K", "10-Q", "Earnings Call")) {
    df_type <- df_all %>% filter(typ == doc_type)
    if(nrow(df_type) == 0) next
    cat(paste0("\n", doc_type, ":\n"))
    for (w in windows) {
      col_name <- paste0("CAR_", w$name)
      mean_car <- mean(df_type[[col_name]], na.rm = TRUE)
      sd_car <- sd(df_type[[col_name]], na.rm = TRUE)
      n_car <- sum(!is.na(df_type[[col_name]]))
      t_stat <- mean_car / (sd_car / sqrt(n_car))
      p_value <- 2 * pt(-abs(t_stat), df = n_car - 1)
      cat(paste(w$label, "- Średni CAR:", round(mean_car, 5), 
                "(t =", round(t_stat, 3), ", p =", round(p_value, 4), ")\n"))
    }
  }
  
  # === TABELA 24: TEST H4 Porównanie CAR między HIGH a LOW  ===
  cat("\n--- TABELA 24: TEST HIPOTEZY H4 – Porównanie CAR między HIGH a LOW  ---\n")
  ev_summary <- list()
  for(doc_type in c("10-K", "10-Q", "Earnings Call")) {
    df_type <- df_all %>% filter(typ == doc_type)
    if(nrow(df_type) == 0) next
    
    for (w in windows) {
      col_name <- paste0("CAR_", w$name)
      df_clean <- df_type %>% filter(!is.na(.data[[col_name]]))
      
      if (nrow(df_clean) >= 10 && length(unique(df_clean$ai_intensity)) == 2) {
        df_clean$ai_intensity <- relevel(factor(df_clean$ai_intensity), ref = "LOW")
        model <- lm(as.formula(paste(col_name, "~ ai_intensity + factor(year_calendar)")), data = df_clean)
        wilcox_t <- wilcox.test(as.formula(paste(col_name, "~ ai_intensity")), data = df_clean)
        
        if ("ai_intensityHIGH" %in% rownames(summary(model)$coefficients)) {
          
          # ZMIANA: Zastosowanie estymatora CR2
          res_cr2 <- clubSandwich::coef_test(model, vcov = "CR2", cluster = df_clean$spolka)
          
          ev_summary[[length(ev_summary)+1]] <- data.frame(
            Typ = doc_type, Okno = w$label,
            Mean_HIGH = round(mean(df_clean[[col_name]][df_clean$ai_intensity == "HIGH"]), 5),
            Mean_LOW = round(mean(df_clean[[col_name]][df_clean$ai_intensity == "LOW"]), 5),
            SD_HIGH = round(sd(df_clean[[col_name]][df_clean$ai_intensity == "HIGH"]), 5),
            SD_LOW = round(sd(df_clean[[col_name]][df_clean$ai_intensity == "LOW"]), 5),
            Median_HIGH = round(median(df_clean[[col_name]][df_clean$ai_intensity == "HIGH"]), 5),
            Median_LOW = round(median(df_clean[[col_name]][df_clean$ai_intensity == "LOW"]), 5),
            T_stat = round(res_cr2["ai_intensityHIGH", "tstat"], 3),
            P_val_T_test = round(res_cr2["ai_intensityHIGH", "p_Satt"], 4), # Pobiera p-value Satterthwaite'a
            P_val_Wilcoxon = round(wilcox_t$p.value, 4),
            N_HIGH = sum(df_clean$ai_intensity == "HIGH"),
            N_LOW = sum(df_clean$ai_intensity == "LOW")
          )
        }
      }
    }
  }
  if(length(ev_summary) > 0) {
    final_table <- bind_rows(ev_summary)
    rownames(final_table) <- NULL  
    print(final_table)
  }
  
  cat("\n--- TABELA 26: TEST BMP ---\n")
  for(doc_type in c("10-K", "10-Q", "Earnings Call")) {
    df_type <- df_all %>% filter(typ == doc_type, !is.na(CAR_m1_1))
    if(nrow(df_type) < 10) next
    
    # ===== BMP dla całej próby (przed podziałem) =====
    scars_all <- sapply(1:nrow(df_type), function(i) {
      calculate_sar(df_type$event_date[i], df_type$spolka[i], prices_wide, -1, 1)
    })
    scars_all <- scars_all[!is.na(scars_all)]
    n_all <- length(scars_all)
    z_all <- mean(scars_all) / (sd(scars_all) / sqrt(n_all))
    p_all <- 2 * pt(-abs(z_all), df = n_all - 1)
    
    cat(paste0("\n--- BMP: ", doc_type, " (cała próba) ---\n"))
    cat(paste("Mean_SCAR =", round(mean(scars_all), 4), 
              "| Z =", round(z_all, 3), 
              "| p =", round(p_all, 4), 
              "| n =", n_all, "\n"))
    
    # ===== BMP dla grup HIGH/LOW =====
    df_type$SCAR <- scars_all
    df_type <- df_type[!is.na(df_type$SCAR), ]
    
    if(nrow(df_type) > 0 && length(unique(df_type$ai_intensity)) == 2) {
      bmp_results <- df_type %>% group_by(ai_intensity) %>%
        summarise(
          Mean_SCAR = round(mean(SCAR), 4), 
          SD_SCAR = round(sd(SCAR), 3),
          n = n(), 
          BMP_Z = round(mean(SCAR) / (sd(SCAR) / sqrt(n())), 3),
          p_value = round(2 * pt(-abs(mean(SCAR) / (sd(SCAR) / sqrt(n()))), df = n() - 1), 4), 
          .groups = "drop"
        )
      cat(paste0("\n--- BMP: ", doc_type, " (podział HIGH/LOW) ---\n"))
      print(bmp_results)
    }
  }
  
  cat("\n--- ANALIZA WOLUMENU ---\n")
  for(doc_type in c("10-K", "10-Q", "Earnings Call")) {
    df_type <- df_all %>% filter(typ == doc_type, !is.na(ai_intensity))
    if(nrow(df_type) == 0) next
    df_type$Volume_Change <- sapply(1:nrow(df_type), function(i) {
      calculate_volume_change(df_type[i, ], volumes_wide, -1, 1, 1)
    })
    df_clean <- df_type %>% filter(abs(Volume_Change) <= 200, !is.na(Volume_Change))
    if(nrow(df_clean) > 0 && length(unique(df_clean$ai_intensity)) == 2) {
      vol_high <- mean(df_clean$Volume_Change[df_clean$ai_intensity == "HIGH"], na.rm = TRUE)
      vol_low <- mean(df_clean$Volume_Change[df_clean$ai_intensity == "LOW"], na.rm = TRUE)
      vol_test <- t.test(Volume_Change ~ ai_intensity, data = df_clean)
      cat(paste0("\n--- WOLUMEN: ", doc_type, " ---\n"))
      cat(paste("Średnia zmiana HIGH:", round(vol_high, 1), "% | LOW:", round(vol_low, 1), "%\n"))
      cat(paste("p-value:", round(vol_test$p.value, 4)))
      if(vol_test$p.value < 0.05) cat(" ✅ Istotna różnica\n") else cat(" ❌ Brak istotnej różnicy\n")
    }
  }
  
  
  df_all$CAR_t0 <- sapply(1:nrow(df_all), function(i) {
    calculate_car_t0(df_all$event_date[i], df_all$spolka[i], prices_wide)
  })
  cat("\n--- SPECYFIKACJA T+0 (dzień publikacji) dla 10-K ---\n")
  k10_t0 <- df_all %>% filter(typ == "10-K", year_calendar %in% c("2022","2023","2024","2025"),
                              !is.na(CAR_t0), !is.na(ai_intensity))
  k10_t0_clean <- k10_t0 
  if (nrow(k10_t0_clean) >= 10 && length(unique(k10_t0_clean$ai_intensity)) == 2) {
    k10_t0_clean$ai_intensity <- relevel(factor(k10_t0_clean$ai_intensity), ref = "LOW")
    model_k10_t0 <- lm(CAR_t0 ~ ai_intensity + factor(year_calendar), data = k10_t0_clean)
    coef_high_k10 <- summary(model_k10_t0)$coefficients["ai_intensityHIGH", ]
    wilcox_k10_t0 <- wilcox.test(CAR_t0 ~ ai_intensity, data = k10_t0_clean)
    cat(paste("Różnica HIGH vs LOW:", round(coef_high_k10[1], 5), "\n"))
    cat(paste("p-value (t):", round(coef_high_k10[4], 4), "\n"))
    cat(paste("p-value (Mann-Whitney):", round(wilcox_k10_t0$p.value, 4), "\n"))
  } else {
    cat("Za mało obserwacji (n =", nrow(k10_t0_clean), ")\n")
  }
  
  cat("\n--- SPECYFIKACJA T+0 (dzień publikacji) dla Earnings Calls ---\n")
  ec_t0 <- df_all %>% filter(typ == "Earnings Call", year_calendar %in% c("2022","2023","2024","2025"),
                             !is.na(CAR_t0), !is.na(ai_intensity))
  ec_t0_clean <- ec_t0 
  if (nrow(ec_t0_clean) >= 10 && length(unique(ec_t0_clean$ai_intensity)) == 2) {
    ec_t0_clean$ai_intensity <- relevel(factor(ec_t0_clean$ai_intensity), ref = "LOW")
    model_t0 <- lm(CAR_t0 ~ ai_intensity + factor(year_calendar), data = ec_t0_clean)
    coef_high_t0 <- summary(model_t0)$coefficients["ai_intensityHIGH", ]
    wilcox_t0 <- wilcox.test(CAR_t0 ~ ai_intensity, data = ec_t0_clean)
    cat(paste("Różnica HIGH vs LOW:", round(coef_high_t0[1], 5), "\n"))
    cat(paste("p-value (t):", round(coef_high_t0[4], 4), "\n"))
    cat(paste("p-value (Mann-Whitney):", round(wilcox_t0$p.value, 4), "\n"))
  }
  
  cat("\n--- SPECYFIKACJA T+0 (dzień publikacji) dla 10-Q ---\n")
  k10q_t0 <- df_all %>% filter(typ == "10-Q", year_calendar %in% c("2022","2023","2024","2025"),
                               !is.na(CAR_t0), !is.na(ai_intensity))
  k10q_t0_clean <- k10q_t0 
  if (nrow(k10q_t0_clean) >= 10 && length(unique(k10q_t0_clean$ai_intensity)) == 2) {
    k10q_t0_clean$ai_intensity <- relevel(factor(k10q_t0_clean$ai_intensity), ref = "LOW")
    model_k10q_t0 <- lm(CAR_t0 ~ ai_intensity + factor(year_calendar), data = k10q_t0_clean)
    coef_high_k10q <- summary(model_k10q_t0)$coefficients["ai_intensityHIGH", ]
    wilcox_k10q_t0 <- wilcox.test(CAR_t0 ~ ai_intensity, data = k10q_t0_clean)
    cat(paste("Różnica HIGH vs LOW:", round(coef_high_k10q[1], 5), "\n"))
    cat(paste("p-value (t):", round(coef_high_k10q[4], 4), "\n"))
    cat(paste("p-value (Mann-Whitney):", round(wilcox_k10q_t0$p.value, 4), "\n"))
  } else {
    cat("Za mało obserwacji (n =", nrow(k10q_t0_clean), ")\n")
  }
  
  cat("\n--- 10-K BEZ ROKU 2022 ---\n")
  k10_no2022 <- df_all %>% filter(typ == "10-K", year_calendar %in% c("2023","2024","2025"),
                                  !is.na(CAR_m1_1), !is.na(ai_intensity))
  if (nrow(k10_no2022) >= 10 && length(unique(k10_no2022$ai_intensity)) == 2) {
    k10_no2022$ai_intensity <- relevel(factor(k10_no2022$ai_intensity), ref = "LOW")
    model_k10_no2022 <- lm(CAR_m1_1 ~ ai_intensity + factor(year_calendar), data = k10_no2022)
    coef_high_k10_no2022 <- summary(model_k10_no2022)$coefficients["ai_intensityHIGH", ]
    wilcox_k10_no2022 <- wilcox.test(CAR_m1_1 ~ ai_intensity, data = k10_no2022)
    cat(paste("Różnica HIGH vs LOW:", round(coef_high_k10_no2022[1], 5), "\n"))
    cat(paste("p-value (t):", round(coef_high_k10_no2022[4], 4), "\n"))
    cat(paste("p-value (Mann-Whitney):", round(wilcox_k10_no2022$p.value, 4), "\n"))
  } else {
    cat("Za mało obserwacji (n =", nrow(k10_no2022), ")\n")
  }
  
  cat("\n--- EARNINGS CALLS BEZ ROKU 2022 ---\n")
  ec_no2022 <- df_all %>% filter(typ == "Earnings Call", year_calendar %in% c("2023","2024","2025"),
                                 !is.na(CAR_m1_1), !is.na(ai_intensity))
  if (nrow(ec_no2022) >= 10 && length(unique(ec_no2022$ai_intensity)) == 2) {
    ec_no2022$ai_intensity <- relevel(factor(ec_no2022$ai_intensity), ref = "LOW")
    model_no2022 <- lm(CAR_m1_1 ~ ai_intensity + factor(year_calendar), data = ec_no2022)
    coef_high_no2022 <- summary(model_no2022)$coefficients["ai_intensityHIGH", ]
    wilcox_no2022 <- wilcox.test(CAR_m1_1 ~ ai_intensity, data = ec_no2022)
    cat(paste("Różnica HIGH vs LOW:", round(coef_high_no2022[1], 5), "\n"))
    cat(paste("p-value (t):", round(coef_high_no2022[4], 4), "\n"))
    cat(paste("p-value (Mann-Whitney):", round(wilcox_no2022$p.value, 4), "\n"))
  }
  
  cat("\n--- 10-Q BEZ ROKU 2022 ---\n")
  k10q_no2022 <- df_all %>% filter(typ == "10-Q", year_calendar %in% c("2023","2024","2025"),
                                   !is.na(CAR_m1_1), !is.na(ai_intensity))
  if (nrow(k10q_no2022) >= 10 && length(unique(k10q_no2022$ai_intensity)) == 2) {
    k10q_no2022$ai_intensity <- relevel(factor(k10q_no2022$ai_intensity), ref = "LOW")
    model_k10q_no2022 <- lm(CAR_m1_1 ~ ai_intensity + factor(year_calendar), data = k10q_no2022)
    coef_high_k10q_no2022 <- summary(model_k10q_no2022)$coefficients["ai_intensityHIGH", ]
    wilcox_k10q_no2022 <- wilcox.test(CAR_m1_1 ~ ai_intensity, data = k10q_no2022)
    cat(paste("Różnica HIGH vs LOW:", round(coef_high_k10q_no2022[1], 5), "\n"))
    cat(paste("p-value (t):", round(coef_high_k10q_no2022[4], 4), "\n"))
    cat(paste("p-value (Mann-Whitney):", round(wilcox_k10q_no2022$p.value, 4), "\n"))
  } else {
    cat("Za mało obserwacji (n =", nrow(k10q_no2022), ")\n")
  }
  
  # ============================================================
  # PLACEBO TEST (walidacja metody)
  # ============================================================
  cat("\n", strrep("=", 70), "\n")
  cat("PLACEBO TEST – LOSOWE PRZESUNIĘCIE DAT ZDARZEŃ\n")
  cat(strrep("=", 70), "\n")
  
  set.seed(123)
  
  # Dla Earnings Calls (najwięcej obserwacji)
  df_placebo <- df_all %>% filter(typ == "Earnings Call")
  
  # Losowe przesunięcie dat o -60, -30, +30, +60 dni
  shifts <- sample(c(-60, -30, 30, 60), nrow(df_placebo), replace = TRUE)
  df_placebo$placebo_date <- df_placebo$event_date + shifts
  
  # Oblicz CAR dla placebo
  df_placebo$CAR_placebo <- sapply(1:nrow(df_placebo), function(i) {
    calculate_car(df_placebo$placebo_date[i], df_placebo$spolka[i], prices_wide, -1, 1)
  })
  
  # Test t dla CAR placebo
  mean_placebo <- mean(df_placebo$CAR_placebo, na.rm = TRUE)
  sd_placebo <- sd(df_placebo$CAR_placebo, na.rm = TRUE)
  n_placebo <- sum(!is.na(df_placebo$CAR_placebo))
  t_placebo <- mean_placebo / (sd_placebo / sqrt(n_placebo))
  p_placebo <- 2 * pt(-abs(t_placebo), df = n_placebo - 1)
  
  cat("\n--- Placebo test (losowe przesunięcie dat o ±30-60 dni) ---\n")
  cat(paste("Średni CAR placebo:", round(mean_placebo, 6), "\n"))
  cat(paste("t-stat:", round(t_placebo, 3), "\n"))
  cat(paste("p-value:", round(p_placebo, 4), "\n"))
  
  if(p_placebo < 0.05) {
    cat("⚠️ UWAGA: Placebo CAR jest istotne – metoda może być błędna!\n")
  } else {
    cat("✅ Placebo CAR nieistotne – metoda event study działa poprawnie.\n")
  }
  
  # Dodatkowo: powtórz 100 razy 
  cat("\n--- Placebo test – wielokrotny (100 powtórzeń) ---\n")
  set.seed(123)
  p_values_placebo <- replicate(100, {
    shifts_rep <- sample(c(-60, -30, 30, 60), nrow(df_placebo), replace = TRUE)
    placebo_date_rep <- df_placebo$event_date + shifts_rep
    car_placebo_rep <- sapply(1:nrow(df_placebo), function(i) {
      calculate_car(placebo_date_rep[i], df_placebo$spolka[i], prices_wide, -1, 1)
    })
    t_test_rep <- t.test(car_placebo_rep[!is.na(car_placebo_rep)])
    t_test_rep$p.value
  })
  
  cat(paste("Średnia p-value z 100 placebo testów:", round(mean(p_values_placebo), 4), "\n"))
  cat(paste("Odsetek istotnych (p < 0.05):", round(mean(p_values_placebo < 0.05) * 100, 1), "%\n"))
  
  if(mean(p_values_placebo < 0.05) < 5) {
    cat("✅ Mniej niż 5% placebo testów istotnych – metoda działa poprawnie.\n")
  } else {
    cat("⚠️ Ponad 5% placebo testów istotnych – potencjalny problem.\n")
  }
  
  # ============================================================
  # ROZSZERZONE MODELE REGRESYJNE H4 (z kontrolami i FE)
  # ============================================================
  
  # Przygotowanie danych dla EC
  dane_reg <- df_all %>%
    filter(typ == "Earnings Call",
           year_calendar %in% c("2022","2023","2024","2025"),
           !is.na(CAR_m1_1)) %>%
    mutate(
      AI_Intensity = density,
      AI_HIGH = ifelse(ai_intensity == "HIGH", 1, 0),
      SUE = eps_surprise,
      firm_id = as.factor(spolka),
      year_id = as.factor(year_calendar)
    )
  
  # ===== DIAGNOSTYKA MODELU REGRESYJNEGO (EC) =====
  cat("\n", strrep("=", 70), "\n")
  cat("DIAGNOSTYKA MODELU REGRESYJNEGO (Earnings Calls)\n")
  cat(strrep("=", 70), "\n")
  
  # 1. Test normalności (Shapiro-Wilk) dla CAR
  car_values <- dane_reg$CAR_m1_1[!is.na(dane_reg$CAR_m1_1)]
  if(length(car_values) >= 3 && length(car_values) <= 5000) {
    sw_test <- shapiro.test(car_values)
    cat("\n--- Test Shapiro-Wilka (normalność CAR) ---\n")
    print(sw_test)
    if(sw_test$p.value < 0.05) cat("⚠️ Rozkład CAR nie jest normalny – uzasadnienie dla testu Manna-Whitneya\n")
  }
  
  # 2. Test Levene'a (równość wariancji między HIGH a LOW)
  if (requireNamespace("car", quietly = TRUE)) {
    lev_test <- suppressWarnings(car::leveneTest(CAR_m1_1 ~ ai_intensity, data = dane_reg))
    cat("\n--- Test Levene'a (równość wariancji HIGH vs LOW) ---\n")
    print(lev_test)
    if(!is.na(lev_test$`Pr(>F)`[1]) && lev_test$`Pr(>F)`[1] < 0.05) {
      cat("⚠️ Wariancje różne – test t może być nieodpowiedni\n")
    } else {
      cat("✅ Wariancje równe – test t odpowiedni\n")
    }
  }
  
  # 3. VIF (współliniowość AI i SUE)
  m2_vif <- lm(CAR_m1_1 ~ AI_Intensity + SUE, data = dane_reg)
  if (requireNamespace("car", quietly = TRUE)) {
    vif_vals <- car::vif(m2_vif)
    cat("\n--- VIF (współliniowość AI i SUE) ---\n")
    print(vif_vals)
    if(any(vif_vals > 5)) cat("⚠️ Współliniowość między zmiennymi\n") else cat("✅ Brak istotnej współliniowości\n")
  }
  
  # 4. Test Breuscha-Pagana (heteroskedastyczność)
  bp_test <- lmtest::bptest(m2_vif)
  cat("\n--- Test Breuscha-Pagana (heteroskedastyczność) ---\n")
  print(bp_test)
  if(bp_test$p.value < 0.05) cat("✅ Heteroskedastyczność – uzasadnienie dla HC3")
  
  cat("\n", strrep("=", 70), "\n")
  cat("ROZSZERZONE MODELE REGRESYJNE H4 (z kontrolami i FE)\n")
  cat(strrep("=", 70), "\n")
  
  # ===== MODEL 1: samo AI =====
  cat("\n--- MODEL 1: CAR ~ AI (HC3) ---\n")
  m1_lin <- lm(CAR_m1_1 ~ AI_Intensity, data = dane_reg)
  m1_bin <- lm(CAR_m1_1 ~ AI_HIGH, data = dane_reg)
  
  # HC3 z sandwich + lmtest
  cr2_m1_lin <- lmtest::coeftest(m1_lin, vcov = sandwich::vcovHC(m1_lin, type = "HC3"))
  cr2_m1_bin <- lmtest::coeftest(m1_bin, vcov = sandwich::vcovHC(m1_bin, type = "HC3"))
  
  cat("Zmienna ciągła (HC3):\n")
  print(cr2_m1_lin["AI_Intensity", , drop=FALSE])
  
  cat("Zmienna binarna (HIGH vs LOW) (HC3):\n")
  print(cr2_m1_bin["AI_HIGH", , drop=FALSE])
  
  # ===== MODEL 2: AI + SUE =====
  cat("\n--- MODEL 2: CAR ~ AI + SUE (HC3) ---\n")
  m2_lin <- lm(CAR_m1_1 ~ AI_Intensity + SUE, data = dane_reg)
  m2_bin <- lm(CAR_m1_1 ~ AI_HIGH + SUE, data = dane_reg)
  
  cr2_m2_lin <- lmtest::coeftest(m2_lin, vcov = sandwich::vcovHC(m2_lin, type = "HC3"))
  cr2_m2_bin <- lmtest::coeftest(m2_bin, vcov = sandwich::vcovHC(m2_bin, type = "HC3"))
  
  cat("Zmienna ciągła + SUE (HC3):\n")
  print(cr2_m2_lin[c("AI_Intensity", "SUE"), ])
  
  cat("Zmienna binarna + SUE (HC3):\n")
  print(cr2_m2_bin[c("AI_HIGH", "SUE"), ])
  
  # ===== MODEL 3: AI + SUE + FE (firma + rok) z CR2 =====
  cat("\n--- MODEL 3: CAR ~ AI + SUE + FE(firma, rok) + CR2 ---\n")
  
  m3_lin <- lm(CAR_m1_1 ~ AI_Intensity + SUE + firm_id + year_id, data = dane_reg)
  m3_bin <- lm(CAR_m1_1 ~ AI_HIGH      + SUE + firm_id + year_id, data = dane_reg)
  
  if (requireNamespace("clubSandwich", quietly = TRUE)) {
    # Obliczamy i przypisujemy CR2 do zmiennych dla modelu 3
    cr2_m3_lin <- clubSandwich::coef_test(m3_lin, vcov = "CR2", cluster = dane_reg$firm_id)
    cr2_m3_bin <- clubSandwich::coef_test(m3_bin, vcov = "CR2", cluster = dane_reg$firm_id)
    
    cat("Zmienna ciągła + FE (CR2):\n")
    df_cr2_lin <- as.data.frame(cr2_m3_lin)
    print(df_cr2_lin[rownames(df_cr2_lin) %in% c("AI_Intensity", "SUE"), c("beta", "SE", "p_Satt")])
    
    cat("Zmienna binarna + FE (CR2):\n")
    df_cr2_bin <- as.data.frame(cr2_m3_bin)
    print(df_cr2_bin[rownames(df_cr2_bin) %in% c("AI_HIGH", "SUE"), c("beta", "SE", "p_Satt")]) 
    
    # ===== PODSUMOWANIE MODELI – WSPÓŁCZYNNIK DLA AI =====
    cat("\n", strrep("=", 70), "\n")
    cat("PODSUMOWANIE MODELI – WSPÓŁCZYNNIK DLA AI\n")
    cat(strrep("=", 70), "\n")
    
    # Funkcja pomocnicza do wyciągania wartości z coeftest
    get_coef_hc3 <- function(obj, var_name) {
      if (var_name %in% rownames(obj)) {
        return(list(
          beta = round(obj[var_name, "Estimate"], 5),
          p = round(obj[var_name, "Pr(>|t|)"], 4)
        ))
      } else {
        return(list(beta = NA, p = NA))
      }
    }
    
    # Dla clubSandwich (CR2)
    get_coef_cr2 <- function(obj, var_name) {
      if (var_name %in% rownames(obj)) {
        return(list(
          beta = round(obj[var_name, "beta"], 5),
          p = round(obj[var_name, "p_Satt"], 4)
        ))
      } else {
        return(list(beta = NA, p = NA))
      }
    }
    
    # Pobierz wartości
    c1_lin <- get_coef_hc3(cr2_m1_lin, "AI_Intensity")
    c1_bin <- get_coef_hc3(cr2_m1_bin, "AI_HIGH")
    c2_lin <- get_coef_hc3(cr2_m2_lin, "AI_Intensity")
    c2_bin <- get_coef_hc3(cr2_m2_bin, "AI_HIGH")
    c3_lin <- get_coef_cr2(cr2_m3_lin, "AI_Intensity")
    c3_bin <- get_coef_cr2(cr2_m3_bin, "AI_HIGH")
    
    summary_h4 <- data.frame(
      Model = c("M1: Samo AI (ciągłe)", "M1: Samo AI (binarne)",
                "M2: + SUE (ciągłe)", "M2: + SUE (binarne)",
                "M3: + FE (ciągłe, CR2)", "M3: + FE (binarne, CR2)"),
      Wspolczynnik = round(c(c1_lin$beta, c1_bin$beta, c2_lin$beta, c2_bin$beta, c3_lin$beta, c3_bin$beta), 5),
      P_value = round(c(c1_lin$p, c1_bin$p, c2_lin$p, c2_bin$p, c3_lin$p, c3_bin$p), 4)
    )
    
    summary_h4$Istotne <- ifelse(summary_h4$P_value < 0.05, "✅", "❌")
    print(summary_h4)
    
    if(any(summary_h4$P_value < 0.05, na.rm = TRUE)) {
      cat("\n✅ β1 JEST ISTOTNE w co najmniej jednym modelu – rynek reaguje na AI\n")
    } else {
      cat("\n❌ β1 NIE JEST ISTOTNE w żadnym modelu – brak dowodu na reakcję rynku na AI\n")
    }
    
    # ============================================================
    # TEST CORRADO
    # ============================================================
    cat("\n", strrep("=", 70), "\n")
    cat("TEST CORRADO\n")
    cat(strrep("=", 70), "\n")
    
    corrado_test_proper <- function(event_dates, firms, 
                                    est_window = 120,
                                    ev_start = -1, ev_end = 1) {
      
      n <- length(event_dates)
      Z_avg <- NA
      p_avg <- NA
      
      if (n < 5) return(list(day_results = NA, Z_sum = NA, p_sum = NA, n = n))
      
      ev_days <- ev_start:ev_end
      n_ev <- length(ev_days)
      
      all_ar <- matrix(NA, nrow = n, ncol = est_window + n_ev)
      colnames(all_ar) <- c(paste0("est_", 1:est_window), paste0("ev_", ev_days))
      
      for (i in 1:n) {
        event_date <- event_dates[i]
        firm <- firms[i]
        
        idx_pub <- which(prices_wide$data >= event_date)
        if (length(idx_pub) == 0) next
        idx_pub <- min(idx_pub)
        if (abs(prices_wide$data[idx_pub] - event_date) > 3) next
        
        event_idx <- idx_pub + 1
        if (event_idx < 2 || event_idx > nrow(prices_wide)) next
        
        est_start <- event_idx - est_window
        est_end <- event_idx - 1
        if (est_start < 2) next
        
        est_returns <- data.frame(
          firm = diff(log(prices_wide[[firm]][(est_start-1):est_end])),
          market = diff(log(prices_wide$SPX[(est_start-1):est_end]))
        )
        est_returns <- est_returns[!is.na(est_returns$firm) & !is.na(est_returns$market), ]
        if (nrow(est_returns) < 10) next
        
        model <- lm(firm ~ market, data = est_returns)
        alpha <- coef(model)[1]
        beta <- coef(model)[2]
        
        for (d in 1:est_window) {
          day_idx <- est_start + d - 1
          if (day_idx < 2 || day_idx > nrow(prices_wide)) next
          firm_ret <- log(prices_wide[[firm]][day_idx] / prices_wide[[firm]][day_idx - 1])
          market_ret <- log(prices_wide$SPX[day_idx] / prices_wide$SPX[day_idx - 1])
          if (!is.na(firm_ret) && !is.na(market_ret)) {
            all_ar[i, paste0("est_", d)] <- firm_ret - (alpha + beta * market_ret)
          }
        }
        
        for (j in 1:n_ev) {
          d <- ev_days[j]
          day_idx <- event_idx + d
          if (day_idx < 2 || day_idx > nrow(prices_wide)) next
          firm_ret <- log(prices_wide[[firm]][day_idx] / prices_wide[[firm]][day_idx - 1])
          market_ret <- log(prices_wide$SPX[day_idx] / prices_wide$SPX[day_idx - 1])
          if (!is.na(firm_ret) && !is.na(market_ret)) {
            all_ar[i, paste0("ev_", d)] <- firm_ret - (alpha + beta * market_ret)
          }
        }
      }
      
      results <- data.frame(Dzien = ev_days, Z = NA, p = NA, N = NA)
      K_matrix <- matrix(NA, nrow = n, ncol = n_ev)
      
      for (j in 1:n_ev) {
        day_col <- paste0("ev_", ev_days[j])
        valid_rows <- which(!is.na(all_ar[, day_col]))
        
        if (length(valid_rows) < 5) next
        
        K_vals <- numeric(length(valid_rows))
        
        for (k in 1:length(valid_rows)) {
          i <- valid_rows[k]
          est_cols <- grep("^est_", colnames(all_ar), value = TRUE)
          est_ars <- all_ar[i, est_cols]
          est_ars <- est_ars[!is.na(est_ars)]
          
          if (length(est_ars) < 10) {
            K_vals[k] <- NA
            next
          }
          
          ar_t <- all_ar[i, day_col]
          all_ars <- c(est_ars, ar_t)
          T_total <- length(all_ars)
          rank_t <- rank(all_ars, na.last = "keep")[T_total]
          K_vals[k] <- (rank_t - (T_total + 1) / 2) / sqrt(((T_total - 1) * (T_total + 1)) / 12)
          K_matrix[i, j] <- K_vals[k]
        }
        
        K_vals <- K_vals[!is.na(K_vals)]
        if (length(K_vals) >= 5) {
          L_t <- mean(K_vals)
          Z_t <- L_t * sqrt(length(K_vals))
          p_t <- 2 * (1 - pnorm(abs(Z_t)))
          results[j, "Z"] <- round(Z_t, 4)
          results[j, "p"] <- round(p_t, 4)
          results[j, "N"] <- length(K_vals)
        }
      }
      
      cat("\n--- Wyniki dla poszczególnych dni ---\n")
      print(results)
      
      cat("\n--- Test łączny dla całego okna ---\n")
      K_sum <- apply(K_matrix, 1, function(row) {
        if (all(is.na(row))) return(NA)
        row_clean <- row[!is.na(row)]
        if (length(row_clean) == 0) return(NA)
        return(mean(row_clean))
      })
      
      K_sum <- K_sum[!is.na(K_sum)]
      
      if (length(K_sum) >= 5) {
        L_avg <- mean(K_sum)
        Z_avg <- L_avg * sqrt(length(K_sum))
        p_avg <- 2 * (1 - pnorm(abs(Z_avg)))
        cat(sprintf("Z = %.4f, p = %.4f, n = %d\n", Z_avg, p_avg, length(K_sum)))
        if (p_avg < 0.05) cat("✅ Istotne\n") else cat("❌ Nieistotne\n")
      } else {
        cat("Za mało obserwacji do testu łącznego\n")
      }
      
      return(list(day_results = results, Z_sum = Z_avg, p_sum = p_avg))
    }
    
    for(doc_type in c("10-K", "10-Q", "Earnings Call")) {
      cat(sprintf("\n=== %s ===\n", doc_type))
      
      df_doc <- df_all %>% 
        filter(typ == doc_type,
               year_calendar %in% c("2022", "2023", "2024", "2025"),
               !is.na(event_date), !is.na(spolka))
      
      if (nrow(df_doc) >= 10) {
        corrado_test_proper(
          event_dates = df_doc$event_date,
          firms = df_doc$spolka,
          est_window = 120,
          ev_start = -1,
          ev_end = 1
        )
      } else {
        cat(sprintf("Za mało obserwacji: n = %d\n", nrow(df_doc)))
      }
    }
  }
  # ===== URUCHOMIENIE ALTERNATYWNYCH TESTÓW =====
  alt_test_results <- run_alternative_tests(df_all)
  assign("df_all", df_all, envir = .GlobalEnv)
  summary_h4 <<- summary_h4
  alt_test_results <<- alt_test_results
  prices_wide <<- prices_wide
  return(list(events_all = df_all, alt_tests = alt_test_results))
}

# =====================================================================
# 10. FUNKCJA GŁÓWNA
# =====================================================================

main <- function() {
  cat("\n")
  cat("████████████████████████████████████████████████████████████████████\n")
  cat("██              MASTER ANALYSIS SCRIPT – WSZYSTKIE ZAŁĄCZNIKI     ██\n")
  cat("██            Analiza ujawnień AI w raportach 10-K, 10-Q, EC      ██\n")
  cat("████████████████████████████████████████████████████████████████████\n")
  
  
  # ===== ZAŁĄCZNIK 2 =====
  results_10k <- analyze_10k_full(folder_10k)
  
  # ===== ZAŁĄCZNIK 2.1 =====
  if (!is.null(results_10k)) {
    narrative_results <- analyze_narrative_sections(folder_narrative, results_10k)
  }
  
  # ===== ZAŁĄCZNIK 3 =====
  results_10q_obj <- analyze_10q_full(folder_10q)
  if (!is.null(results_10q_obj)) {
    results_10q_raw <- results_10q_obj$raw
    results_10q_annual <- results_10q_obj$annual
  } else {
    results_10q_raw <- NULL
    results_10q_annual <- NULL
  }
  
  # ===== ZAŁĄCZNIK 4 =====
  results_ec <- analyze_earnings_calls_full(folder_ec, results_10k, results_10q_annual)
  
  # ===== ZAŁĄCZNIK 5 (Zintegrowane z wynikami EC) =====
  if (!is.null(results_10k)) {
    rd_capex_results <- analyze_rd_capex_full(results_10k, results_ec)
  }
  
  # ===== ZAŁĄCZNIK 6 =====
  if (!is.null(results_10k) && !is.null(results_ec)) {
    qualitative_results <- qualitative_summary_full(results_10k, results_ec)
  }
  
  # ===== ZAŁĄCZNIK 7 =====
  if (!is.null(results_10k) && !is.null(results_10q_raw) && !is.null(results_ec)) {
    event_results <- analyze_event_study(folder_prices, ALL_AI_TERMS_SORTED)
  }
  
  # ===== PODSUMOWANIE KOŃCOWE =====
  cat("\n", strrep("=", 70), "\n")
  cat("PODSUMOWANIE HIPOTEZ\n")
  cat(strrep("=", 70), "\n")
  cat("H1: Sekcje narracyjne gęstsze niż finansowa ✅\n")
  cat("H2: Earnings Calls > 10-K > 10-Q ✅\n")
  cat("H3: CAPEX istotny, R&D nie ❌\n")
  cat("H4: AI nie wpływa na CAR ❌\n")
  cat(strrep("=", 70), "\n")
  
  cat("\n", strrep("=", 70), "\n")
  cat("WSZYSTKIE ANALIZY ZAKOŃCZONE POMYŚLNIE!\n")
  cat(strrep("=", 70), "\n")
  
  assign("results_10k", results_10k, envir = .GlobalEnv)
  if (exists("results_10q_annual")) assign("results_10q_annual", results_10q_annual, envir = .GlobalEnv)
  if (exists("results_10q_raw")) assign("results_10q_raw", results_10q_raw, envir = .GlobalEnv)
  assign("results_ec", results_ec, envir = .GlobalEnv)
  if (exists("narrative_results")) assign("narrative_results", narrative_results, envir = .GlobalEnv)
  if (exists("rd_capex_results")) assign("rd_capex_results", rd_capex_results, envir = .GlobalEnv)
  if (exists("qualitative_results")) assign("qualitative_results", qualitative_results, envir = .GlobalEnv)
  if (exists("event_results")) assign("event_results", event_results, envir = .GlobalEnv)
  
  # Zapisz wszystkie kluczowe obiekty do pliku
  save(
    results_10k,
    results_10q_raw,
    results_10q_annual,
    results_ec,
    narrative_results,
    rd_capex_results,
    qualitative_results,
    event_results,
    fe_capex, fe_rd, fe_full,          
    summary_h4, alt_test_results,      
    file = "wyniki_analizy.RData"
  )
  
  cat("\n✅ Zapisano wyniki do pliku: wyniki_analizy.RData\n")
  
}

# URUCHOMIENIE CAŁOŚCI
main()
Konsola serwera
Konsola gotowa.