package autoregister

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"text/template"

	"go.uber.org/zap"
)

// Generator 代码生成器
type Generator struct {
	logger *zap.Logger
}

// NewGenerator 创建新的代码生成器
func NewGenerator(logger *zap.Logger) *Generator {
	return &Generator{
		logger: logger,
	}
}

// GenerateRegistrationCode 生成注册代码
func (g *Generator) GenerateRegistrationCode(services []*ServiceInfo, outputPath string) error {
	tmpl := `// Code generated by go-grpc-kit autoregister. DO NOT EDIT.

package main

import (
{{range .Imports}}	"{{.}}"
{{end}}
	"google.golang.org/grpc"
)

// AutoRegisterServices 自动注册所有服务
func AutoRegisterServices(server grpc.ServiceRegistrar) {
{{range .Services}}	// Register {{.TypeName}}
	{{.PackageName}}.Register{{.ServiceName}}Server(server, &{{.PackageName}}.{{.TypeName}}{})
{{end}}
}

// GetAutoRegisteredServices 获取自动注册的服务列表
func GetAutoRegisteredServices() []string {
	return []string{
{{range .Services}}		"{{.ServiceName}}",
{{end}}	}
}
`

	// 准备模板数据
	data := struct {
		Imports  []string
		Services []*ServiceInfo
	}{
		Imports:  g.extractImports(services),
		Services: services,
	}

	// 解析模板
	t, err := template.New("registration").Parse(tmpl)
	if err != nil {
		return fmt.Errorf("failed to parse template: %w", err)
	}

	// 创建输出目录
	if err := os.MkdirAll(filepath.Dir(outputPath), 0755); err != nil {
		return fmt.Errorf("failed to create output directory: %w", err)
	}

	// 创建输出文件
	file, err := os.Create(outputPath)
	if err != nil {
		return fmt.Errorf("failed to create output file: %w", err)
	}
	defer file.Close()

	// 执行模板
	if err := t.Execute(file, data); err != nil {
		return fmt.Errorf("failed to execute template: %w", err)
	}

	g.logger.Info("Generated auto-registration code",
		zap.String("output", outputPath),
		zap.Int("services", len(services)))

	return nil
}

// extractImports 提取导入包
func (g *Generator) extractImports(services []*ServiceInfo) []string {
	imports := make(map[string]bool)
	
	for _, service := range services {
		// 从文件路径推断包路径
		// 这里需要根据实际的项目结构来调整
		packagePath := g.inferPackagePath(service.FilePath)
		if packagePath != "" {
			imports[packagePath] = true
		}
	}

	var result []string
	for imp := range imports {
		result = append(result, imp)
	}
	
	return result
}

// inferPackagePath 推断包路径
func (g *Generator) inferPackagePath(filePath string) string {
	// 这里需要根据项目的模块路径来推断
	// 简化实现，实际使用时需要更复杂的逻辑
	
	// 假设项目结构为 github.com/user/project/...
	// 需要从 go.mod 文件中读取模块路径
	
	dir := filepath.Dir(filePath)
	
	// 移除常见的前缀路径
	if strings.Contains(dir, "/pkg/") {
		parts := strings.Split(dir, "/pkg/")
		if len(parts) > 1 {
			return "github.com/go-grpc-kit/go-grpc-kit/pkg/" + parts[1]
		}
	}
	
	return ""
}