-- Migration 015: Vitals Refactoring - Trennung Baseline vs. Context-Dependent
-- v9d Phase 2d: Architektur-Verbesserung für bessere Datenqualität
-- Date: 2026-03-23

-- ══════════════════════════════════════════════════════════════════════════════
-- STEP 1: Create new tables
-- ══════════════════════════════════════════════════════════════════════════════

-- Baseline Vitals (slow-changing, once daily, morning measurement)
CREATE TABLE IF NOT EXISTS vitals_baseline (
    id SERIAL PRIMARY KEY,
    profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
    date DATE NOT NULL,

    -- Core baseline vitals
    resting_hr INTEGER CHECK (resting_hr > 0 AND resting_hr < 120),
    hrv INTEGER CHECK (hrv > 0 AND hrv < 300),
    vo2_max DECIMAL(4,1) CHECK (vo2_max > 0 AND vo2_max < 100),
    spo2 INTEGER CHECK (spo2 >= 70 AND spo2 <= 100),
    respiratory_rate DECIMAL(4,1) CHECK (respiratory_rate > 0 AND respiratory_rate < 60),

    -- Future baseline vitals (prepared for expansion)
    body_temperature DECIMAL(3,1) CHECK (body_temperature > 30 AND body_temperature < 45),
    resting_metabolic_rate INTEGER CHECK (resting_metabolic_rate > 0),

    -- Metadata
    note TEXT,
    source VARCHAR(20) DEFAULT 'manual' CHECK (source IN ('manual', 'apple_health', 'garmin', 'withings')),
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),

    CONSTRAINT unique_baseline_per_day UNIQUE(profile_id, date)
);

CREATE INDEX idx_vitals_baseline_profile_date ON vitals_baseline(profile_id, date DESC);

COMMENT ON TABLE vitals_baseline IS 'v9d Phase 2d: Baseline vitals measured once daily (morning, fasted)';
COMMENT ON COLUMN vitals_baseline.resting_hr IS 'Resting heart rate (bpm) - measured in the morning before getting up';
COMMENT ON COLUMN vitals_baseline.hrv IS 'Heart rate variability (ms) - higher is better';
COMMENT ON COLUMN vitals_baseline.vo2_max IS 'VO2 Max (ml/kg/min) - estimated by Apple Watch or lab test';
COMMENT ON COLUMN vitals_baseline.spo2 IS 'Blood oxygen saturation (%) - baseline measurement';
COMMENT ON COLUMN vitals_baseline.respiratory_rate IS 'Respiratory rate (breaths/min) - baseline measurement';

-- ══════════════════════════════════════════════════════════════════════════════

-- Blood Pressure Log (context-dependent, multiple times per day)
CREATE TABLE IF NOT EXISTS blood_pressure_log (
    id SERIAL PRIMARY KEY,
    profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
    measured_at TIMESTAMP NOT NULL,

    -- Blood pressure measurements
    systolic INTEGER NOT NULL CHECK (systolic > 0 AND systolic < 300),
    diastolic INTEGER NOT NULL CHECK (diastolic > 0 AND diastolic < 200),
    pulse INTEGER CHECK (pulse > 0 AND pulse < 250),

    -- Context tagging for correlation analysis
    context VARCHAR(30) CHECK (context IN (
        'morning_fasted',    -- Morgens nüchtern
        'after_meal',        -- Nach dem Essen
        'before_training',   -- Vor dem Training
        'after_training',    -- Nach dem Training
        'evening',           -- Abends
        'stress',            -- Bei Stress
        'resting',           -- Ruhemessung
        'other'              -- Sonstiges
    )),

    -- Warning flags (Omron)
    irregular_heartbeat BOOLEAN DEFAULT false,
    possible_afib BOOLEAN DEFAULT false,

    -- Metadata
    note TEXT,
    source VARCHAR(20) DEFAULT 'manual' CHECK (source IN ('manual', 'omron', 'apple_health', 'withings')),
    created_at TIMESTAMP DEFAULT NOW(),

    CONSTRAINT unique_bp_measurement UNIQUE(profile_id, measured_at)
);

CREATE INDEX idx_blood_pressure_profile_datetime ON blood_pressure_log(profile_id, measured_at DESC);
CREATE INDEX idx_blood_pressure_context ON blood_pressure_log(context) WHERE context IS NOT NULL;

COMMENT ON TABLE blood_pressure_log IS 'v9d Phase 2d: Blood pressure measurements (multiple per day, context-aware)';
COMMENT ON COLUMN blood_pressure_log.context IS 'Measurement context for correlation analysis';
COMMENT ON COLUMN blood_pressure_log.irregular_heartbeat IS 'Irregular heartbeat detected (Omron device)';
COMMENT ON COLUMN blood_pressure_log.possible_afib IS 'Possible atrial fibrillation (Omron device)';

-- ══════════════════════════════════════════════════════════════════════════════
-- STEP 2: Migrate existing data from vitals_log
-- ══════════════════════════════════════════════════════════════════════════════

-- Migrate baseline vitals (RHR, HRV, VO2 Max, SpO2, Respiratory Rate)
INSERT INTO vitals_baseline (
    profile_id, date,
    resting_hr, hrv, vo2_max, spo2, respiratory_rate,
    note, source, created_at, updated_at
)
SELECT
    profile_id, date,
    resting_hr, hrv, vo2_max, spo2, respiratory_rate,
    note, source, created_at, updated_at
FROM vitals_log
WHERE resting_hr IS NOT NULL
   OR hrv IS NOT NULL
   OR vo2_max IS NOT NULL
   OR spo2 IS NOT NULL
   OR respiratory_rate IS NOT NULL
ON CONFLICT (profile_id, date) DO NOTHING;

-- Migrate blood pressure measurements
-- Note: Use date + 08:00 as default timestamp (morning measurement)
INSERT INTO blood_pressure_log (
    profile_id, measured_at,
    systolic, diastolic, pulse,
    irregular_heartbeat, possible_afib,
    note, source, created_at
)
SELECT
    profile_id,
    (date + TIME '08:00:00')::timestamp AS measured_at,
    blood_pressure_systolic,
    blood_pressure_diastolic,
    pulse,
    irregular_heartbeat,
    possible_afib,
    note,
    CASE
        WHEN source = 'manual' THEN 'manual'
        WHEN source = 'omron' THEN 'omron'
        ELSE 'manual'
    END AS source,
    created_at
FROM vitals_log
WHERE blood_pressure_systolic IS NOT NULL
  AND blood_pressure_diastolic IS NOT NULL
ON CONFLICT (profile_id, measured_at) DO NOTHING;

-- ══════════════════════════════════════════════════════════════════════════════
-- STEP 3: Drop old vitals_log table (backup first)
-- ══════════════════════════════════════════════════════════════════════════════

-- Rename old table as backup (keep for safety, can be dropped later)
ALTER TABLE vitals_log RENAME TO vitals_log_backup_pre_015;

-- Drop old index (it's on the renamed table now)
DROP INDEX IF EXISTS idx_vitals_profile_date;

-- ══════════════════════════════════════════════════════════════════════════════
-- STEP 4: Prepared for future vitals types
-- ══════════════════════════════════════════════════════════════════════════════

-- Future tables (commented out, create when needed):

-- Glucose Log (for blood sugar tracking)
-- CREATE TABLE glucose_log (
--     id SERIAL PRIMARY KEY,
--     profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
--     measured_at TIMESTAMP NOT NULL,
--     glucose_mg_dl INTEGER NOT NULL CHECK (glucose_mg_dl > 0 AND glucose_mg_dl < 500),
--     context VARCHAR(30) CHECK (context IN (
--         'fasted', 'before_meal', 'after_meal_1h', 'after_meal_2h', 'before_training', 'after_training', 'other'
--     )),
--     note TEXT,
--     source VARCHAR(20) DEFAULT 'manual',
--     created_at TIMESTAMP DEFAULT NOW(),
--     CONSTRAINT unique_glucose_measurement UNIQUE(profile_id, measured_at)
-- );

-- Temperature Log (for illness tracking)
-- CREATE TABLE temperature_log (
--     id SERIAL PRIMARY KEY,
--     profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
--     measured_at TIMESTAMP NOT NULL,
--     temperature_celsius DECIMAL(3,1) NOT NULL CHECK (temperature_celsius > 30 AND temperature_celsius < 45),
--     measurement_location VARCHAR(20) CHECK (measurement_location IN ('oral', 'ear', 'forehead', 'armpit')),
--     note TEXT,
--     created_at TIMESTAMP DEFAULT NOW(),
--     CONSTRAINT unique_temperature_measurement UNIQUE(profile_id, measured_at)
-- );

-- ══════════════════════════════════════════════════════════════════════════════
-- Migration complete
-- ══════════════════════════════════════════════════════════════════════════════
