---
title: "iFlex Workflow with Shipped Example Data"
author: "elcf4R package"
output:
  rmarkdown::html_vignette:
    toc: true
vignette: >
  %\VignetteIndexEntry{iFlex Workflow with Shipped Example Data}
  %\VignetteEngine{knitr::rmarkdown}
  \usepackage[utf8]{inputenc}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
library(elcf4R)
lstm_available <- getFromNamespace(
  ".elcf4r_lstm_backend_available",
  "elcf4R"
)()
```

# Overview

This vignette shows a complete lightweight workflow using only datasets that
ship with the package:

- `elcf4r_iflex_example` for preprocessing and model fitting examples.
- `elcf4r_iflex_benchmark_results` for inspecting saved benchmark results.

# Inspect the shipped iFlex example

```{r}
dim(elcf4r_iflex_example)
length(unique(elcf4r_iflex_example$entity_id))
range(elcf4r_iflex_example$timestamp)
head(elcf4r_iflex_example[, c("entity_id", "timestamp", "y", "temp")])
```

# Build daily segments

We work on one participant to keep the example compact.

```{r}
id1 <- subset(
  elcf4r_iflex_example,
  entity_id == unique(elcf4r_iflex_example$entity_id)[1]
)

daily <- elcf4r_build_daily_segments(
  id1,
  carry_cols = c("participation_phase", "price_signal")
)

dim(daily$segments)
head(daily$covariates[, c("date", "dow", "temp_mean", "participation_phase")])
```

# Fit forecasting models on the example panel

We train on the first 10 days and predict the 11th day.

```{r}
train_days <- daily$covariates$date[1:10]
test_day <- daily$covariates$date[11]

train_long <- subset(id1, date %in% train_days)
test_long <- subset(id1, date == test_day)

fit_gam <- elcf4r_fit_gam(
  train_long[, c("y", "time_index", "dow", "month", "temp")],
  use_temperature = TRUE
)
pred_gam <- predict(
  fit_gam,
  newdata = test_long[, c("y", "time_index", "dow", "month", "temp")]
)

fit_mars <- elcf4r_fit_mars(
  train_long[, c("y", "time_index", "dow", "month", "temp")],
  use_temperature = TRUE
)
pred_mars <- predict(
  fit_mars,
  newdata = test_long[, c("y", "time_index", "dow", "month", "temp")]
)

fit_kwf <- elcf4r_fit_kwf(
  segments = daily$segments[1:10, ],
  covariates = daily$covariates[1:10, , drop = FALSE],
  target_covariates = daily$covariates[11, , drop = FALSE]
)
pred_kwf <- predict(fit_kwf)

fit_kwf_clustered <- elcf4r_fit_kwf_clustered(
  segments = daily$segments[1:10, ],
  covariates = daily$covariates[1:10, , drop = FALSE],
  target_covariates = daily$covariates[11, , drop = FALSE]
)
pred_kwf_clustered <- predict(fit_kwf_clustered)

naive_day <- as.numeric(daily$segments[10, ])

rbind(
  gam = unlist(elcf4r_metrics(test_long$y, pred_gam, naive_pred = naive_day)),
  mars = unlist(elcf4r_metrics(test_long$y, pred_mars, naive_pred = naive_day)),
  kwf = unlist(elcf4r_metrics(test_long$y, pred_kwf, naive_pred = naive_day)),
  kwf_clustered = unlist(elcf4r_metrics(test_long$y, pred_kwf_clustered, naive_pred = naive_day))
)
```

An LSTM example is available when the `keras3` and `tensorflow` packages are
installed and Python has been selected explicitly for `reticulate`, for example
with `elcf4r_use_tensorflow_env()` or `reticulate::use_virtualenv()` before
rendering this vignette:

```{r, eval = lstm_available}
fit_lstm <- elcf4r_fit_lstm(
  segments = daily$segments[1:10, ],
  covariates = daily$covariates[1:10, , drop = FALSE],
  use_temperature = TRUE,
  epochs = 1,
  units = 4,
  batch_size = 2,
  verbose = 0
)

pred_lstm <- predict(fit_lstm)
unlist(elcf4r_metrics(test_long$y, pred_lstm, naive_pred = naive_day))
```

```{r, eval = !lstm_available}
"LSTM example skipped because no explicit Keras/TensorFlow backend is configured in this R environment."
```

# Run a small rolling benchmark

The package also exposes a reusable rolling-origin benchmark runner that works
on normalized panels produced by the `elcf4r_read_*()` adapters.

```{r}
benchmark_index <- elcf4r_build_benchmark_index(
  elcf4r_iflex_example,
  carry_cols = c("dataset", "participation_phase", "price_signal")
)

benchmark_small <- elcf4r_benchmark(
  panel = elcf4r_iflex_example,
  benchmark_index = benchmark_index,
  methods = c("gam", "kwf"),
  cohort_size = 1,
  train_days = 10,
  test_days = 2,
  include_predictions = FALSE
)

benchmark_small$results
```

# Inspect shipped benchmark results

The package also ships precomputed benchmark results on a fixed iFlex cohort.
In the current build these results cover `gam`, `mars`, `kwf`,
`kwf_clustered` and `lstm`.

```{r}
head(elcf4r_iflex_benchmark_results)

aggregate(
  cbind(nmae, nrmse, smape, mase, fit_seconds) ~ method,
  data = elcf4r_iflex_benchmark_results,
  FUN = function(x) round(mean(x, na.rm = TRUE), 4)
)
```

This object is intended to support reproducible package examples and to provide
a stable reference point for future benchmark extensions.
