package com.cameleer.server.app.storage;

import com.cameleer.server.core.admin.AppSettings;
import com.cameleer.server.core.admin.AppSettingsRepository;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public class PostgresAppSettingsRepository implements AppSettingsRepository {

    private final JdbcTemplate jdbc;

    private static final RowMapper<AppSettings> ROW_MAPPER = (rs, rowNum) -> new AppSettings(
            rs.getString("application_id"),
            rs.getString("environment"),
            rs.getInt("sla_threshold_ms"),
            rs.getDouble("health_error_warn"),
            rs.getDouble("health_error_crit"),
            rs.getDouble("health_sla_warn"),
            rs.getDouble("health_sla_crit"),
            rs.getTimestamp("created_at").toInstant(),
            rs.getTimestamp("updated_at").toInstant());

    public PostgresAppSettingsRepository(JdbcTemplate jdbc) {
        this.jdbc = jdbc;
    }

    @Override
    public Optional<AppSettings> findByApplicationAndEnvironment(String applicationId, String environment) {
        List<AppSettings> results = jdbc.query(
                "SELECT * FROM app_settings WHERE application_id = ? AND environment = ?",
                ROW_MAPPER, applicationId, environment);
        return results.isEmpty() ? Optional.empty() : Optional.of(results.get(0));
    }

    @Override
    public List<AppSettings> findByEnvironment(String environment) {
        return jdbc.query(
                "SELECT * FROM app_settings WHERE environment = ? ORDER BY application_id",
                ROW_MAPPER, environment);
    }

    @Override
    public AppSettings save(AppSettings settings) {
        jdbc.update("""
                INSERT INTO app_settings (application_id, environment, sla_threshold_ms, health_error_warn,
                    health_error_crit, health_sla_warn, health_sla_crit, created_at, updated_at)
                VALUES (?, ?, ?, ?, ?, ?, ?, now(), now())
                ON CONFLICT (application_id, environment) DO UPDATE SET
                    sla_threshold_ms  = EXCLUDED.sla_threshold_ms,
                    health_error_warn = EXCLUDED.health_error_warn,
                    health_error_crit = EXCLUDED.health_error_crit,
                    health_sla_warn   = EXCLUDED.health_sla_warn,
                    health_sla_crit   = EXCLUDED.health_sla_crit,
                    updated_at        = now()
                """,
                settings.applicationId(), settings.environment(), settings.slaThresholdMs(),
                settings.healthErrorWarn(), settings.healthErrorCrit(),
                settings.healthSlaWarn(), settings.healthSlaCrit());
        return findByApplicationAndEnvironment(settings.applicationId(), settings.environment()).orElseThrow();
    }

    @Override
    public void delete(String appId, String environment) {
        jdbc.update("DELETE FROM app_settings WHERE application_id = ? AND environment = ?",
                appId, environment);
    }
}
