package com.cameleer.server.app.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

@Component
public class ClickHouseSchemaInitializer {

    private static final Logger log = LoggerFactory.getLogger(ClickHouseSchemaInitializer.class);

    private final JdbcTemplate clickHouseJdbc;

    public ClickHouseSchemaInitializer(
            @Qualifier("clickHouseJdbcTemplate") JdbcTemplate clickHouseJdbc) {
        this.clickHouseJdbc = clickHouseJdbc;
    }

    @EventListener(ApplicationReadyEvent.class)
    public void initializeSchema() {
        runScript("clickhouse/init.sql");
        runScript("clickhouse/alerting_projections.sql");
    }

    private void runScript(String classpathResource) {
        try {
            PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource script = resolver.getResource("classpath:" + classpathResource);

            String sql = script.getContentAsString(StandardCharsets.UTF_8);
            log.info("Executing ClickHouse schema: {}", script.getFilename());
            for (String statement : sql.split(";")) {
                String trimmed = statement.trim();
                // Skip empty segments and comment-only segments
                String withoutComments = trimmed.lines()
                        .filter(line -> !line.stripLeading().startsWith("--"))
                        .map(String::trim)
                        .filter(line -> !line.isEmpty())
                        .reduce("", (a, b) -> a + b);
                if (!withoutComments.isEmpty()) {
                    String upper = withoutComments.toUpperCase();
                    boolean isBestEffort = upper.contains("MATERIALIZE PROJECTION")
                            || upper.contains("ADD PROJECTION");
                    try {
                        clickHouseJdbc.execute(trimmed);
                    } catch (Exception e) {
                        if (isBestEffort) {
                            // ADD PROJECTION on ReplacingMergeTree requires a session setting not available
                            // via JDBC pool; MATERIALIZE can fail on empty tables — both are non-fatal.
                            log.warn("Projection DDL step skipped (non-fatal): {} — {}",
                                    trimmed.substring(0, Math.min(trimmed.length(), 120)), e.getMessage());
                        } else {
                            throw e;
                        }
                    }
                }
            }

            log.info("ClickHouse schema script complete: {}", script.getFilename());
        } catch (Exception e) {
            log.error("ClickHouse schema script failed [{}] — server will continue but ClickHouse features may not work",
                    classpathResource, e);
        }
    }
}
