package com.lingyue.graph.config;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.neo4j.driver.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import jakarta.annotation.PreDestroy;

/**
 * Neo4j 配置类
 * 
 * 使用 Neo4j Java Driver 连接图数据库
 * 
 * 配置示例（application.yml）:
 * neo4j:
 *   enabled: true
 *   uri: bolt://localhost:7687
 *   username: neo4j
 *   password: your-password
 *   database: neo4j
 *   connection-timeout: 30s
 *   max-connection-pool-size: 50
 * 
 * @author lingyue
 * @since 2026-01-21
 */
@Slf4j
@Data
@Configuration
@ConfigurationProperties(prefix = "neo4j")
public class Neo4jConfig {
    
    /**
     * 是否启用 Neo4j（默认禁用，便于开发测试）
     */
    private boolean enabled = false;
    
    /**
     * Neo4j 连接 URI
     * 格式: bolt://host:port 或 neo4j://host:port
     */
    private String uri = "bolt://localhost:7687";
    
    /**
     * 用户名
     */
    private String username = "neo4j";
    
    /**
     * 密码
     */
    private String password;
    
    /**
     * 数据库名称（Neo4j 4.0+ 支持多数据库）
     */
    private String database = "neo4j";
    
    /**
     * 连接超时时间（秒）
     */
    private int connectionTimeoutSeconds = 30;
    
    /**
     * 最大连接池大小
     */
    private int maxConnectionPoolSize = 50;
    
    private Driver driver;
    
    /**
     * 创建 Neo4j Driver Bean
     */
    @Bean
    @ConditionalOnProperty(name = "neo4j.enabled", havingValue = "true")
    public Driver neo4jDriver() {
        log.info("初始化 Neo4j 连接: uri={}, database={}", uri, database);
        
        Config config = Config.builder()
                .withConnectionTimeout(connectionTimeoutSeconds, java.util.concurrent.TimeUnit.SECONDS)
                .withMaxConnectionPoolSize(maxConnectionPoolSize)
                .withDriverMetrics()
                .build();
        
        // 支持无密码模式（当 Neo4j 禁用认证时）
        AuthToken auth;
        if (password == null || password.isEmpty()) {
            auth = AuthTokens.none();
            log.info("Neo4j 使用无认证模式连接");
        } else {
            auth = AuthTokens.basic(username, password);
        }
        
        this.driver = GraphDatabase.driver(uri, auth, config);
        
        // 验证连接
        try {
            driver.verifyConnectivity();
            log.info("Neo4j 连接成功");
        } catch (Exception e) {
            log.error("Neo4j 连接失败: {}", e.getMessage());
            throw new RuntimeException("无法连接到 Neo4j: " + e.getMessage(), e);
        }
        
        return driver;
    }
    
    /**
     * 关闭连接
     */
    @PreDestroy
    public void close() {
        if (driver != null) {
            log.info("关闭 Neo4j 连接");
            driver.close();
        }
    }
}
