package at.procon.eventhub.persistence;

import at.procon.eventhub.dto.EventSourceDto;
import java.sql.PreparedStatement;
import java.sql.Statement;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class EventSourceRepository {

    private final JdbcTemplate jdbcTemplate;

    public EventSourceRepository(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public int resolveSourceId(String tenantKey, EventSourceDto eventSource) {
        String normalizedTenantKey = tenantKey == null || tenantKey.isBlank() ? "default" : tenantKey.trim();
        Integer existing = findSourceId(normalizedTenantKey, eventSource);
        if (existing != null) {
            return existing;
        }

        jdbcTemplate.update(connection -> {
            PreparedStatement ps = connection.prepareStatement(
                    """
                    insert into eventhub.event_source(
                        tenant_key, provider_key, source_kind, source_key, source_instance_key,
                        tenant_provider_setting_key, external_fleet_key
                    ) values (?, ?, ?, ?, ?, ?, ?)
                    on conflict (tenant_key, provider_key, source_kind, source_key, source_instance_key) do nothing
                    """,
                    Statement.NO_GENERATED_KEYS
            );
            ps.setString(1, normalizedTenantKey);
            ps.setString(2, eventSource.providerKey());
            ps.setString(3, eventSource.sourceKind());
            ps.setString(4, eventSource.sourceKey());
            ps.setString(5, eventSource.sourceInstanceKey() == null ? "default" : eventSource.sourceInstanceKey());
            ps.setString(6, eventSource.tenantProviderSettingKey());
            ps.setString(7, eventSource.externalFleetKey());
            return ps;
        });

        Integer created = findSourceId(normalizedTenantKey, eventSource);
        if (created == null) {
            throw new IllegalStateException("Could not resolve event source id for " + normalizedTenantKey + ":" + eventSource.stableKey());
        }
        return created;
    }

    private Integer findSourceId(String tenantKey, EventSourceDto eventSource) {
        return jdbcTemplate.query(
                """
                select id
                from eventhub.event_source
                where tenant_key = ?
                  and provider_key = ?
                  and source_kind = ?
                  and source_key = ?
                  and source_instance_key = ?
                """,
                rs -> rs.next() ? rs.getInt("id") : null,
                tenantKey,
                eventSource.providerKey(),
                eventSource.sourceKind(),
                eventSource.sourceKey(),
                eventSource.sourceInstanceKey() == null ? "default" : eventSource.sourceInstanceKey()
        );
    }
}
