-- =============================================================
-- Hrubý odhad „kolik by přineslo přesunout ~30 kWh/den“ z levných
-- slotů (OTE sell < práh) do večerních/ranních špiček.
--
-- Zjednodušení:
--   • Kalendářní den v Europe/Prague.
--   • Bereme jen dny, kde existuje aspoň jeden 15min slot s sell < :cheap_thr.
--   • „Levná“ strana: průměrná OTE sell ve všech slotech toho dne s sell < :cheap_thr.
--   • „Drahá“ strana: okno večer+ráno (18:00–24:00 a 0:00–8:00), seřadíme sloty
--     podle ceny DESC, vyhodíme :drop_top nejvyšších (malá baterie je už „sežere“),
--     vezmeme dalších :take_slot 15min intervalů → :take_slot × 0,25 h × 12 kW = 30 kWh
--     při 12 kW a take_slot = 10.
--   • Hrubý přínos (Kč/den) ≈ :shift_kwh * (avg_peak - avg_cheap); bez účinnosti baterie.
--
-- Uprav parametry v nejníže (date_trunc rozsah, práhy, počty slotů).
-- Spuštění: psql -v ON_ERROR_STOP=1 -f scripts/analysis/ote_arbitrage_proxy.sql
-- =============================================================

WITH params AS (
    SELECT
        0.3::numeric AS cheap_thr,
        0::int AS drop_top,      -- vynechat N nejdražších 15min ve večer+ráno okně
        12::int AS take_slot,   -- dalších N slotů = 2,5 h při 15 min
        30::numeric AS shift_kwh -- objem energie pro hrubý spread (volitelně = take_slot * 0.25 * 12)
),
slots AS (
    SELECT
        interval_start,
        (interval_start AT TIME ZONE 'Europe/Prague')::date AS d,
        (interval_start AT TIME ZONE 'Europe/Prague')::time AS t,
        sell_raw_price_czk_kwh::numeric AS sell
    FROM ems.market_interval_price
    WHERE market_source = 'OTE_CZ'
      AND interval_start >= TIMESTAMPTZ '2025-04-01 Europe/Prague'
      AND interval_start < TIMESTAMPTZ '2026-04-01 Europe/Prague'
),
days_cheap AS (
    SELECT s.d
    FROM slots s
    GROUP BY s.d
    HAVING MIN(s.sell) < (SELECT cheap_thr FROM params)
),
cheap_side AS (
    SELECT
        s.d,
        AVG(s.sell) AS avg_cheap
    FROM slots s
    INNER JOIN days_cheap dc ON dc.d = s.d
    WHERE s.sell < (SELECT cheap_thr FROM params)
    GROUP BY s.d
),
evening_morning AS (
    SELECT
        s.d,
        s.sell,
        s.t
    FROM slots s
    INNER JOIN days_cheap dc ON dc.d = s.d
    WHERE s.t >= TIME '18:00'
       OR s.t < TIME '08:00'
),
ranked AS (
    SELECT
        em.d,
        em.sell,
        ROW_NUMBER() OVER (PARTITION BY em.d ORDER BY em.sell DESC, em.t) AS rn
    FROM evening_morning em
),
peak_pick AS (
    SELECT
        r.d,
        r.sell
    FROM ranked r
    WHERE r.rn > (SELECT drop_top FROM params)
      AND r.rn <= (SELECT drop_top + take_slot FROM params)
),
peak_side AS (
    SELECT d, AVG(sell) AS avg_peak
    FROM peak_pick
    GROUP BY d
),
per_day AS (
    SELECT
        c.d,
        c.avg_cheap,
        p.avg_peak,
        (SELECT shift_kwh FROM params) * (p.avg_peak - c.avg_cheap) AS rough_kc_day
    FROM cheap_side c
    INNER JOIN peak_side p ON p.d = c.d
),
period AS (
    SELECT
        (TIMESTAMPTZ '2026-04-01 Europe/Prague' - TIMESTAMPTZ '2024-04-01 Europe/Prague')
        AS len
)
SELECT
    COUNT(*)::int AS days_qualifying,
    ROUND(SUM(pd.rough_kc_day)::numeric, 2) AS spread_kc_sum_period,
    ROUND(AVG(pd.rough_kc_day)::numeric, 4) AS spread_kc_avg_per_qualifying_day,
    ROUND(
        (SUM(pd.rough_kc_day) / NULLIF(EXTRACT(EPOCH FROM (SELECT len FROM period)) / 86400.0, 0) * 365.0)::numeric,
        2
    ) AS spread_kc_naive_per_solar_year
FROM per_day pd;
