package main

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
	"gopkg.in/yaml.v3"
)

var (
	// Version information
	version = "v1.0.0"

	// Global flags
	configFile  string
	outputDir   string
	templateDir string
	verbose     bool
)

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
	Use:   "kra-gen",
	Short: "KRA 代码生成工具",
	Long: `KRA 自动代码生成工具，支持生成 Kratos DDD 架构的后端代码和 React 前端代码。

功能特性:
  - 生成符合 Kratos DDD 分层架构的代码（biz/data/service/server）
  - 使用 GORM Gen 生成类型安全的数据库操作代码
  - 生成 React TypeScript 前端代码
  - 支持配置文件和命令行参数两种方式
  - 支持预览模式，不写入文件

使用示例:
  # 从配置文件生成代码
  kra-gen generate -c autocode.yaml

  # 交互模式
  kra-gen generate -i

  # 预览模式
  kra-gen generate -c autocode.yaml -p

  # 查看版本
  kra-gen version`,
	Run: func(cmd *cobra.Command, args []string) {
		// If no subcommand is provided, show help
		cmd.Help()
	},
}

func init() {
	// Global flags
	rootCmd.PersistentFlags().StringVarP(&configFile, "config", "c", "", "配置文件路径 (JSON/YAML)")
	rootCmd.PersistentFlags().StringVarP(&outputDir, "output", "o", "", "输出目录（默认当前项目）")
	rootCmd.PersistentFlags().StringVarP(&templateDir, "template", "t", "", "模板目录（默认 resource/package）")
	rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "显示详细输出")

	// Add subcommands
	rootCmd.AddCommand(versionCmd)
	rootCmd.AddCommand(generateCmd)
	rootCmd.AddCommand(previewCmd)
	rootCmd.AddCommand(listCmd)
}

// versionCmd represents the version command
var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "显示版本信息",
	Long:  "显示 KRA 代码生成工具的版本信息",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Printf("kra-gen %s\n", version)
		fmt.Println("KRA 自动代码生成工具")
		fmt.Println("支持 Kratos DDD 架构 + GORM Gen + React TypeScript")
	},
}

// listCmd represents the list command for listing available templates or packages
var listCmd = &cobra.Command{
	Use:   "list [templates|packages|databases]",
	Short: "列出可用资源",
	Long: `列出可用的模板、包或数据库连接。

使用示例:
  kra-gen list templates    # 列出可用模板
  kra-gen list packages     # 列出已创建的包
  kra-gen list databases    # 列出数据库连接`,
	Args: cobra.MaximumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) == 0 {
			fmt.Println("请指定要列出的资源类型: templates, packages, databases")
			return
		}

		switch args[0] {
		case "templates":
			listTemplates()
		case "packages":
			listPackages()
		case "databases":
			listDatabases()
		default:
			fmt.Printf("未知的资源类型: %s\n", args[0])
			fmt.Println("可用类型: templates, packages, databases")
		}
	},
}

func listTemplates() {
	fmt.Println("可用模板:")
	fmt.Println("  package  - 标准包模板 (Kratos DDD 架构)")
	fmt.Println("  plugin   - 插件模板 (独立功能模块)")
}

func listPackages() {
	// TODO: 实现从数据库或文件系统读取已创建的包
	fmt.Println("已创建的包:")
	fmt.Println("  (需要连接数据库获取)")
}

func listDatabases() {
	// 尝试从配置文件加载数据库连接
	configPath := "configs/config.yaml"
	if _, err := os.Stat(configPath); err != nil {
		fmt.Println("数据库连接:")
		fmt.Println("  未找到配置文件 configs/config.yaml")
		fmt.Println("  请使用 'kra-gen generate -i' 进入交互模式配置数据库")
		return
	}

	data, err := os.ReadFile(configPath)
	if err != nil {
		fmt.Printf("读取配置文件失败: %v\n", err)
		return
	}

	var config struct {
		Mysql struct {
			Path     string `yaml:"path"`
			Port     string `yaml:"port"`
			DBName   string `yaml:"db_name"`
			Username string `yaml:"username"`
		} `yaml:"mysql"`
		Pgsql struct {
			Path     string `yaml:"path"`
			Port     string `yaml:"port"`
			DBName   string `yaml:"db_name"`
			Username string `yaml:"username"`
		} `yaml:"pgsql"`
		Sqlite struct {
			DBName string `yaml:"db_name"`
		} `yaml:"sqlite"`
	}

	if err := yaml.Unmarshal(data, &config); err != nil {
		fmt.Printf("解析配置文件失败: %v\n", err)
		return
	}

	fmt.Println("数据库连接:")
	found := false

	if config.Mysql.Path != "" && config.Mysql.DBName != "" {
		fmt.Printf("  MySQL: %s@%s:%s/%s\n", config.Mysql.Username, config.Mysql.Path, config.Mysql.Port, config.Mysql.DBName)
		found = true
	}

	if config.Pgsql.Path != "" && config.Pgsql.DBName != "" {
		fmt.Printf("  PostgreSQL: %s@%s:%s/%s\n", config.Pgsql.Username, config.Pgsql.Path, config.Pgsql.Port, config.Pgsql.DBName)
		found = true
	}

	if config.Sqlite.DBName != "" {
		fmt.Printf("  SQLite: %s\n", config.Sqlite.DBName)
		found = true
	}

	if !found {
		fmt.Println("  未配置任何数据库连接")
	}
}

// getWorkingDir returns the current working directory or the specified output directory
func getWorkingDir() string {
	if outputDir != "" {
		return outputDir
	}
	dir, err := os.Getwd()
	if err != nil {
		return "."
	}
	return dir
}

// getTemplateDir returns the template directory path
func getTemplateDir() string {
	if templateDir != "" {
		return templateDir
	}
	return "resource/package"
}
