-- =============================================================
-- R__044_fn_set_mode.sql
-- EMS Platform – přepínání provozních režimů
-- Repeatable migration
-- =============================================================

CREATE OR REPLACE FUNCTION ems.fn_set_mode(
    p_site_id    INT,
    p_mode_code  TEXT,
    p_activated_by TEXT DEFAULT 'system',
    p_valid_until  TIMESTAMPTZ DEFAULT NULL,
    p_notes        TEXT DEFAULT NULL
)
RETURNS TEXT
LANGUAGE plpgsql
AS $$
DECLARE
    v_current_mode TEXT;
    v_mode_exists  BOOLEAN;
BEGIN
    -- Ověřit že režim existuje
    SELECT EXISTS(SELECT 1 FROM ems.operating_mode_def WHERE code = p_mode_code)
    INTO v_mode_exists;

    IF NOT v_mode_exists THEN
        RAISE EXCEPTION 'Neznámý provozní režim: %', p_mode_code;
    END IF;

    -- Zjistit aktuální režim (pro log a previous_mode)
    SELECT mode_code INTO v_current_mode
    FROM ems.site_operating_mode
    WHERE site_id = p_site_id;

    -- Pokud se režim nemění, nic nedělat
    IF v_current_mode = p_mode_code THEN
        RETURN p_mode_code;
    END IF;

    -- Uzavřít předchozí záznam v logu
    UPDATE ems.site_operating_mode_log
    SET deactivated_at = now()
    WHERE site_id = p_site_id
      AND deactivated_at IS NULL;

    -- Upsert aktivního režimu
    INSERT INTO ems.site_operating_mode
        (site_id, mode_code, activated_at, activated_by, valid_until, previous_mode, notes)
    VALUES
        (p_site_id, p_mode_code, now(), p_activated_by, p_valid_until, v_current_mode, p_notes)
    ON CONFLICT (site_id) DO UPDATE SET
        mode_code     = EXCLUDED.mode_code,
        activated_at  = EXCLUDED.activated_at,
        activated_by  = EXCLUDED.activated_by,
        valid_until   = EXCLUDED.valid_until,
        previous_mode = EXCLUDED.previous_mode,
        notes         = EXCLUDED.notes;

    -- Přidat záznam do logu
    INSERT INTO ems.site_operating_mode_log
        (site_id, mode_code, activated_at, activated_by, notes)
    VALUES
        (p_site_id, p_mode_code, now(), p_activated_by, p_notes);

    RETURN p_mode_code;
END;
$$;

COMMENT ON FUNCTION ems.fn_set_mode(INT, TEXT, TEXT, TIMESTAMPTZ, TEXT) IS
'Přepne provozní režim lokality. Atomicky aktualizuje site_operating_mode a zapíše do audit logu.
Ignoruje přepnutí na stejný režim. Vyhodí výjimku pro neznámý kód režimu.
Příklad: SELECT ems.fn_set_mode(1, ''SELF_SUSTAIN'', ''user:jan'', NULL, ''Odjezd na dovolenou'');';

-- ============================================================

CREATE OR REPLACE FUNCTION ems.fn_restore_previous_mode(
    p_site_id      INT,
    p_activated_by TEXT DEFAULT 'system'
)
RETURNS TEXT
LANGUAGE plpgsql
AS $$
DECLARE
    v_previous TEXT;
BEGIN
    SELECT previous_mode INTO v_previous
    FROM ems.site_operating_mode
    WHERE site_id = p_site_id;

    IF v_previous IS NULL THEN
        -- Fallback na AUTO pokud není předchozí režim
        v_previous := 'AUTO';
    END IF;

    RETURN ems.fn_set_mode(p_site_id, v_previous, p_activated_by, NULL, 'Obnova předchozího režimu');
END;
$$;

COMMENT ON FUNCTION ems.fn_restore_previous_mode(INT, TEXT) IS
'Přepne lokalitu zpět na předchozí provozní režim (uložený v previous_mode).
Pokud předchozí režim neexistuje, přepne na AUTO. Používat po skončení dočasného přepisu.';

-- ============================================================

drop function if exists ems.fn_expire_modes();

CREATE OR REPLACE FUNCTION ems.fn_expire_modes()
RETURNS TABLE(site_id INT, site_code TEXT, old_mode TEXT, new_mode TEXT)
LANGUAGE plpgsql
AS $$
DECLARE
    v_rec     RECORD;
    v_new_mode TEXT;
BEGIN
    FOR v_rec IN
        SELECT som.site_id,
               s.code AS site_code,
               som.mode_code AS old_mode,
               som.previous_mode
        FROM ems.site_operating_mode som
        JOIN ems.site s ON s.id = som.site_id
        WHERE som.valid_until IS NOT NULL
          AND som.valid_until <= now()
          AND som.mode_code <> 'AUTO'
    LOOP
        v_new_mode := COALESCE(v_rec.previous_mode, 'AUTO');
        PERFORM ems.fn_set_mode(
            v_rec.site_id,
            v_new_mode,
            'system:expiry',
            NULL,
            'Automatické vypršení dočasného režimu'
        );
        site_id := v_rec.site_id;
        site_code := v_rec.site_code;
        old_mode := v_rec.old_mode;
        new_mode := v_new_mode;
        RETURN NEXT;
    END LOOP;
END;
$$;

COMMENT ON FUNCTION ems.fn_expire_modes() IS
'Zkontroluje všechny lokality s dočasným režimem (valid_until IS NOT NULL) a přepne zpět ty s prosahlým časem.
Volat každou minutu jako scheduled task. Vrátí řádky (site_id, site_code, old_mode, new_mode) pro každé provedené přepnutí — backend z toho pošle Discord notifikace.';
