-- Cache delta profilu PV (těžká agregace forecast_accuracy) — refresh po fn_fill_forecast_accuracy.
-- Prefix R__018: musí běžet před R__022 (volá fn_refresh_site_pv_delta_profile_cache).

drop function if exists ems.fn_refresh_site_pv_delta_profile_cache;

create or replace function ems.fn_refresh_site_pv_delta_profile_cache(
  p_site_id int,
  p_force boolean default false
)
returns void
language plpgsql
as $fn$
declare
  v_profile jsonb;
begin
  -- VÝKON: agregace 120 dní nad forecast_accuracy trvá ~44 s/site na prod —
  -- po 15 min ji přepočítávat dusilo celou DB (timeouty API). Profil má 14d
  -- poločas, denní granularitu — čerstvost 6 h bohatě stačí.
  if not p_force and exists (
    select 1 from ems.site_pv_forecast_calibration c
    where c.site_id = p_site_id
      and c.delta_profile_cached_at > now() - interval '6 hours'
  ) then
    return;
  end if;

  v_profile := ems.fn_pv_forecast_delta_profile(
    p_site_id,
    now() - interval '120 days',
    now()
  );

  update ems.site_pv_forecast_calibration c
  set
    delta_profile_cache = v_profile,
    delta_profile_cached_at = now(),
    updated_at = now()
  where c.site_id = p_site_id;

  if not found then
    insert into ems.site_pv_forecast_calibration (
      site_id,
      delta_learn_min_ts,
      delta_profile_cache,
      delta_profile_cached_at
    )
    values (
      p_site_id,
      timestamptz '2026-04-11T22:00:00Z',
      v_profile,
      now()
    );
  end if;
end;
$fn$;

comment on function ems.fn_refresh_site_pv_delta_profile_cache is
  'Přepočte a uloží delta_profile_cache pro site (volá fn_pv_forecast_delta_profile).';

create or replace function ems.fn_pv_forecast_delta_profile_cached(
  p_site_id int,
  p_data_from timestamptz default (now() - interval '120 days'),
  p_data_to timestamptz default now(),
  p_half_life_days numeric default 14,
  p_threshold_w int default 150,
  p_top_n_days int default 3,
  p_non_top_day_factor numeric default 0.02,
  p_day_weight_gamma numeric default 1.0,
  p_max_age interval default interval '30 minutes'
)
returns jsonb
language plpgsql
stable
as $fn$
declare
  v_cached jsonb;
  v_cached_at timestamptz;
begin
  select c.delta_profile_cache, c.delta_profile_cached_at
  into v_cached, v_cached_at
  from ems.site_pv_forecast_calibration c
  where c.site_id = p_site_id;

  -- ČTENÁŘ NIKDY NEPOČÍTÁ (přepočet = 44 s/site na prod!). Vrací cache bez
  -- ohledu na stáří (přepočet řídí výhradně fn_refresh_… — throttle 6 h
  -- z fill_forecast_accuracy ticku + denní catch-up). p_max_age ponechán
  -- v signatuře kvůli kompatibilitě volajících, ignoruje se.
  if v_cached is not null
     and p_data_from >= (now() - interval '121 days')
     and p_data_to <= now() + interval '5 minutes' then
    return v_cached;
  end if;

  -- jen first-run (cache NULL) nebo nestandardní analytické okno:
  return ems.fn_pv_forecast_delta_profile(
    p_site_id,
    p_data_from,
    p_data_to,
    p_half_life_days,
    p_threshold_w,
    p_top_n_days,
    p_non_top_day_factor,
    p_day_weight_gamma
  );
end;
$fn$;

comment on function ems.fn_pv_forecast_delta_profile_cached is
  'Delta profil VŽDY z cache (stáří řídí refresh job, ne čtenář — přepočet 44 s/site); inline přepočet jen first-run / nestandardní okno.';
