-- Signály EMS → externí cíle (Loxone VI, HTTP REST), journal + idempotence + verify readback.
-- Kritické řízení výkonu (Deye, EV, TČ) zůstává v modbus_command / exporteru.

-- ------------------------------------------------------------
-- Definice signálů (globální katalog kódů)
-- ------------------------------------------------------------
CREATE TABLE ems.signal_def (
    code         TEXT PRIMARY KEY,
    value_type   TEXT NOT NULL,
    description  TEXT
);

COMMENT ON TABLE ems.signal_def IS
'Katalog signálů EMS (logické výstupy). Hodnotu pro route počítá backend dle doménové logiky.';

COMMENT ON COLUMN ems.signal_def.code IS
'Unikátní kód signálu, např. EXPORT_BAN_ACTIVE.';

COMMENT ON COLUMN ems.signal_def.value_type IS
'bool | int | float | string — očekávaný typ hodnoty po transformaci na cíl.';

INSERT INTO ems.signal_def (code, value_type, description)
VALUES (
    'EXPORT_BAN_ACTIVE',
    'bool',
    'Pravda pokud EMS aktuálně uplatňuje zákaz exportu do sítě (LED varianta B): override block_export, no_export, režimy bez exportu, AUTO se záporným výkupem při ne-negativním grid setpointu.'
)
ON CONFLICT (code) DO NOTHING;

-- ------------------------------------------------------------
-- Směrování signál → cíl (per site)
-- ------------------------------------------------------------
CREATE TABLE ems.signal_route (
    id                 SERIAL PRIMARY KEY,
    site_id            INT NOT NULL REFERENCES ems.site (id),
    destination_type   TEXT NOT NULL,
    endpoint_id        INT NOT NULL REFERENCES ems.site_endpoint (id),
    signal_code         TEXT NOT NULL REFERENCES ems.signal_def (code),
    destination_key     TEXT NOT NULL,
    route_config_json   JSONB,
    transform_json      JSONB,
    verify_readback     BOOLEAN NOT NULL DEFAULT true,
    verify_config_json  JSONB,
    enabled               BOOLEAN NOT NULL DEFAULT true,
    created_at            TIMESTAMPTZ NOT NULL DEFAULT now(),
    CONSTRAINT uq_signal_route_unique UNIQUE (site_id, destination_type, signal_code, destination_key)
);

CREATE INDEX idx_signal_route_site_enabled
    ON ems.signal_route (site_id, enabled)
    WHERE enabled = true;

COMMENT ON TABLE ems.signal_route IS
'Mapování signálu na cíl (Loxone Virtual Input, HTTP REST atd.). endpoint_id ukazuje na ems.site_endpoint (loxone_http, budoucí shelly_http, …).';

COMMENT ON COLUMN ems.signal_route.destination_type IS
'loxone_vi = GET /dev/sps/io/{destination_key}/{value}; http_rest = šablona v route_config_json.';

COMMENT ON COLUMN ems.signal_route.destination_key IS
'U Loxone název Virtual Inputu. U HTTP REST stabilní klíč pro log (např. relay0).';

COMMENT ON COLUMN ems.signal_route.route_config_json IS
'Volitelná konfigurace pro http_rest (path_template, method, …). U loxone_vi typicky NULL.';

COMMENT ON COLUMN ems.signal_route.verify_config_json IS
'Readback: u Loxone např. {"loxone_io_name":"EMS_ExportBan_Active_FB"} pro GET /dev/sps/io/{name}. U HTTP JSON path atd.';

-- ------------------------------------------------------------
-- Odchozí journal
-- ------------------------------------------------------------
CREATE TABLE ems.signal_outbound_journal (
    id                   BIGSERIAL PRIMARY KEY,
    route_id             INT NOT NULL REFERENCES ems.signal_route (id),
    site_id              INT NOT NULL REFERENCES ems.site (id),
    signal_code          TEXT NOT NULL,
    value_text           TEXT NOT NULL,
    value_num            NUMERIC,
    status               TEXT NOT NULL,
    attempt_count        INT NOT NULL DEFAULT 0,
    next_attempt_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    last_error            TEXT,
    http_method           TEXT,
    request_url           TEXT,
    http_status           INT,
    latency_ms            INT,
    response_body_trunc   TEXT,
    sent_at               TIMESTAMPTZ,
    verified_at           TIMESTAMPTZ,
    created_at            TIMESTAMPTZ NOT NULL DEFAULT now(),
    CONSTRAINT chk_signal_outbound_status CHECK (
        status IN ('queued', 'sent', 'verified', 'failed', 'abandoned')
    )
);

CREATE INDEX idx_signal_outbound_worker
    ON ems.signal_outbound_journal (status, next_attempt_at);

CREATE INDEX idx_signal_outbound_site_debug
    ON ems.signal_outbound_journal (site_id, signal_code, created_at DESC);

COMMENT ON TABLE ems.signal_outbound_journal IS
'Journal odchozích signálů (HTTP). Worker odesílá queued, po úspěchu sent, po readback verified nebo failed s retry.';

-- ------------------------------------------------------------
-- Poslední známý stav (idempotence)
-- ------------------------------------------------------------
CREATE TABLE ems.signal_state (
    site_id                 INT NOT NULL REFERENCES ems.site (id),
    signal_code             TEXT NOT NULL,
    destination_type        TEXT NOT NULL,
    destination_key         TEXT NOT NULL,
    last_desired_value_text TEXT,
    last_sent_value_text    TEXT,
    last_verified_value_text TEXT,
    last_sent_at             TIMESTAMPTZ,
    last_verified_at         TIMESTAMPTZ,
    updated_at               TIMESTAMPTZ NOT NULL DEFAULT now(),
    PRIMARY KEY (site_id, signal_code, destination_type, destination_key)
);

COMMENT ON TABLE ems.signal_state IS
'Poslední požadovaná / odeslaná / ověřená hodnota signálu per cíl — idempotence a diagnostika verify.';
