"""demo_data.py — 합성 호흡가스/DIT 곡선 절차적 생성.

생성:
1) COSMED 스타일 안정 REE: warm-up 후 안정. (data/demo_cosmed_steady.csv)
2) 불안정 곡선: 드리프트/노이즈 커서 안정 미도달. (data/demo_unstable.csv)
3) DIT 식후 곡선: 기저 후 식사로 EE 상승→감쇠. (data/demo_dit_postprandial.csv)

모든 CSV 는 mL/min 단위(COSMED 관례)로 저장하여 importer 의 단위 자동인식 검증.

본 도구는 연구용·참고용이며 임상 의사결정에 직접 사용 금지.
"""

from __future__ import annotations

import os

import numpy as np
import pandas as pd

DATA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")


def _ensure_dir():
    os.makedirs(DATA_DIR, exist_ok=True)


def make_steady(duration_min=30, seed=11):
    """안정 REE 곡선. 단위 mL/min. 안정구간 VO2~250, VCO2~200 (RQ 0.80)."""
    rng = np.random.default_rng(seed)
    t = np.arange(0, duration_min, 1.0)
    # warm-up 0-6분: 높게 시작해 안정값으로 수렴
    vo2 = np.where(t < 6, 320 - (320 - 250) * (t / 6.0), 250.0)
    vco2 = np.where(t < 6, 270 - (270 - 200) * (t / 6.0), 200.0)
    vo2 = vo2 + rng.normal(0, 2.5, size=t.size)   # 안정구간 CV < 2%
    vco2 = vco2 + rng.normal(0, 2.0, size=t.size)
    return pd.DataFrame({"Time": t, "VO2": vo2, "VCO2": vco2,
                         "RQ": vco2 / vo2})


def make_unstable(duration_min=30, seed=22):
    """불안정 곡선: 지속 드리프트+큰 노이즈로 안정 미도달. 단위 mL/min."""
    rng = np.random.default_rng(seed)
    t = np.arange(0, duration_min, 1.0)
    # 큰 진폭의 빠른 진동 + 지속 드리프트 + 큰 가우시안 노이즈로
    # 어떤 5분 윈도우에서도 CV 가 10% 임계 위에 머물게 한다(안정 미도달 시연).
    vo2 = 260 + 55 * np.sin(t / 1.6) + 1.3 * t + rng.normal(0, 22, size=t.size)
    vco2 = 205 + 48 * np.sin(t / 1.4 + 0.7) + 1.0 * t + rng.normal(0, 20, size=t.size)
    vo2 = np.clip(vo2, 80, None)
    vco2 = np.clip(vco2, 60, None)
    return pd.DataFrame({"Time": t, "VO2": vo2, "VCO2": vco2,
                         "RQ": vco2 / vo2})


def make_dit(duration_min=240, meal_min=30, seed=33):
    """DIT 식후 곡선: 0-30분 기저, 30분 식사 후 EE 상승→지수 감쇠. 단위 mL/min.

    기저 VO2~240(EE~1660 kcal/day). 식후 피크 +18% 후 t1/2 ~60분 감쇠.
    """
    rng = np.random.default_rng(seed)
    t = np.arange(0, duration_min, 5.0)  # 5분 간격
    base_vo2 = 240.0
    base_vco2 = 192.0  # RQ 0.80
    bump = np.zeros_like(t)
    post = t >= meal_min
    tau = 70.0  # 감쇠 시간상수(분)
    peak_frac = 0.18
    bump[post] = peak_frac * np.exp(-(t[post] - meal_min) / tau)
    # 식후 RQ 상승(탄수 산화 증가) 모사: VCO2 가 더 크게 오름
    vo2 = base_vo2 * (1 + bump) + rng.normal(0, 1.5, size=t.size)
    vco2 = base_vco2 * (1 + bump * 1.25) + rng.normal(0, 1.5, size=t.size)
    return pd.DataFrame({"Time": t, "VO2": vo2, "VCO2": vco2,
                         "RQ": vco2 / vo2})


def write_all():
    _ensure_dir()
    paths = {}
    df = make_steady()
    p = os.path.join(DATA_DIR, "demo_cosmed_steady.csv")
    df.to_csv(p, index=False)
    paths["steady"] = p

    df = make_unstable()
    p = os.path.join(DATA_DIR, "demo_unstable.csv")
    df.to_csv(p, index=False)
    paths["unstable"] = p

    df = make_dit()
    p = os.path.join(DATA_DIR, "demo_dit_postprandial.csv")
    df.to_csv(p, index=False)
    paths["dit"] = p
    return paths


if __name__ == "__main__":
    print(write_all())
