package com.cameleer.server.app.alerting.storage;

import com.cameleer.server.app.AbstractPostgresIT;
import com.cameleer.server.app.search.ClickHouseLogStore;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import static org.assertj.core.api.Assertions.assertThat;

class V12MigrationIT extends AbstractPostgresIT {

    @MockBean(name = "clickHouseLogStore")    ClickHouseLogStore    clickHouseLogStore;

    private java.util.UUID testEnvId;
    private String testUserId;

    @AfterEach
    void cleanup() {
        if (testEnvId != null) jdbcTemplate.update("DELETE FROM environments WHERE id = ?", testEnvId);
        if (testUserId != null) jdbcTemplate.update("DELETE FROM users WHERE user_id = ?", testUserId);
    }

    @Test
    void allAlertingTablesAndEnumsExist() {
        var tables = jdbcTemplate.queryForList(
            "SELECT table_name FROM information_schema.tables WHERE table_schema='public' " +
            "AND table_name IN ('alert_rules','alert_rule_targets','alert_instances'," +
            "'alert_silences','alert_notifications','alert_reads')",
            String.class);
        assertThat(tables).containsExactlyInAnyOrder(
            "alert_rules","alert_rule_targets","alert_instances",
            "alert_silences","alert_notifications","alert_reads");

        var enums = jdbcTemplate.queryForList(
            "SELECT typname FROM pg_type WHERE typname IN " +
            "('severity_enum','condition_kind_enum','alert_state_enum'," +
            "'target_kind_enum','notification_status_enum')",
            String.class);
        assertThat(enums).containsExactlyInAnyOrder(
            "severity_enum", "condition_kind_enum", "alert_state_enum",
            "target_kind_enum", "notification_status_enum");
    }

    @Test
    void deletingEnvironmentCascadesAlertingRows() {
        testEnvId = java.util.UUID.randomUUID();
        testUserId = java.util.UUID.randomUUID().toString();

        jdbcTemplate.update(
            "INSERT INTO environments (id, slug, display_name) VALUES (?, ?, ?)",
            testEnvId, "test-cascade-env-" + testEnvId, "Test Cascade Env");
        jdbcTemplate.update(
            "INSERT INTO users (user_id, provider, email) VALUES (?, ?, ?)",
            testUserId, "local", "test@example.com");

        var ruleId = java.util.UUID.randomUUID();
        jdbcTemplate.update(
            "INSERT INTO alert_rules (id, environment_id, name, severity, condition_kind, condition, " +
            "notification_title_tmpl, notification_message_tmpl, created_by, updated_by) " +
            "VALUES (?, ?, 'r', 'WARNING', 'AGENT_STATE', '{}'::jsonb, 't', 'm', ?, ?)",
            ruleId, testEnvId, testUserId, testUserId);

        var instanceId = java.util.UUID.randomUUID();
        jdbcTemplate.update(
            "INSERT INTO alert_instances (id, rule_id, rule_snapshot, environment_id, state, severity, " +
            "fired_at, context, title, message) VALUES (?, ?, '{}'::jsonb, ?, 'FIRING', 'WARNING', " +
            "now(), '{}'::jsonb, 't', 'm')",
            instanceId, ruleId, testEnvId);

        jdbcTemplate.update("DELETE FROM environments WHERE id = ?", testEnvId);

        assertThat(jdbcTemplate.queryForObject(
            "SELECT count(*) FROM alert_rules WHERE environment_id = ?",
            Integer.class, testEnvId)).isZero();
        assertThat(jdbcTemplate.queryForObject(
            "SELECT count(*) FROM alert_instances WHERE environment_id = ?",
            Integer.class, testEnvId)).isZero();

        // testEnvId already deleted; null it so @AfterEach doesn't attempt a no-op delete
        testEnvId = null;
    }
}
