package system

import (
	"context"
	"encoding/json"
	"fmt"
	"go/ast"
	"go/format"
	"go/parser"
	"go/token"
	"os"
	"path/filepath"
	"strings"
	"text/template"

	"github.com/go-kratos/kratos/v2/log"
	"github.com/pkg/errors"
	"gorm.io/gorm"

	"kra/internal/conf"
	"kra/pkg/utils"
	"kra/pkg/utils/autocode"
)

// AutoCodeTemplateRepo 自动代码模板仓储接口
type AutoCodeTemplateRepo interface {
	GetPackageByName(ctx context.Context, packageName string) (*SysAutoCodePackage, error)
	CreateApis(ctx context.Context, apis []SysApi) ([]uint, error)
	GetMenuByName(ctx context.Context, name string) (*SysBaseMenu, error)
	CreateMenu(ctx context.Context, menu *SysBaseMenu) error
	CreateExportTemplate(ctx context.Context, tpl *SysExportTemplate) error
	Repeat(ctx context.Context, businessDB, structName, abbreviation, pkg string) bool
}

// AutoCodeTemplateUsecase 自动代码模板用例
type AutoCodeTemplateUsecase struct {
	repo        AutoCodeTemplateRepo
	historyRepo AutoCodeHistoryRepo
	packageRepo AutoCodePackageRepo
	config      *conf.AutoCodeConfig
	log         *log.Helper
	db          *gorm.DB
}

// NewAutoCodeTemplateUsecase 创建自动代码模板用例
func NewAutoCodeTemplateUsecase(
	repo AutoCodeTemplateRepo,
	historyRepo AutoCodeHistoryRepo,
	packageRepo AutoCodePackageRepo,
	config *conf.AutoCodeConfig,
	logger log.Logger,
	db *gorm.DB,
) *AutoCodeTemplateUsecase {
	return &AutoCodeTemplateUsecase{
		repo:        repo,
		historyRepo: historyRepo,
		packageRepo: packageRepo,
		config:      config,
		log:         log.NewHelper(logger),
		db:          db,
	}
}

// checkPackage 检查包结构是否完整
// 支持 Kratos DDD 层次结构检查：
// - biz/{package}/enter.go - 业务逻辑层入口
// - data/{package}/enter.go - 数据访问层入口
// - service/{package}/enter.go - 服务层入口
// - server/handler/{package}/enter.go - HTTP Handler 层入口
// - server/router/{package}/enter.go - 路由层入口
func (uc *AutoCodeTemplateUsecase) checkPackage(pkg string, template string) error {
	switch template {
	case "package":
		// Kratos DDD 架构目录检查
		// 检查 Biz 层
		bizEnter := filepath.Join(uc.config.Root, uc.config.Server, "internal", "biz", pkg, "enter.go")
		if _, err := os.Stat(bizEnter); err != nil {
			return fmt.Errorf("package结构异常,缺少internal/biz/%s/enter.go", pkg)
		}
		// 检查 Data 层
		dataEnter := filepath.Join(uc.config.Root, uc.config.Server, "internal", "data", pkg, "enter.go")
		if _, err := os.Stat(dataEnter); err != nil {
			return fmt.Errorf("package结构异常,缺少internal/data/%s/enter.go", pkg)
		}
		// 检查 Service 层
		serviceEnter := filepath.Join(uc.config.Root, uc.config.Server, "internal", "service", pkg, "enter.go")
		if _, err := os.Stat(serviceEnter); err != nil {
			return fmt.Errorf("package结构异常,缺少internal/service/%s/enter.go", pkg)
		}
		// 检查 Handler 层
		handlerEnter := filepath.Join(uc.config.Root, uc.config.Server, "internal", "server", "handler", pkg, "enter.go")
		if _, err := os.Stat(handlerEnter); err != nil {
			return fmt.Errorf("package结构异常,缺少internal/server/handler/%s/enter.go", pkg)
		}
		// 检查 Router 层
		routerEnter := filepath.Join(uc.config.Root, uc.config.Server, "internal", "server", "router", pkg, "enter.go")
		if _, err := os.Stat(routerEnter); err != nil {
			return fmt.Errorf("package结构异常,缺少internal/server/router/%s/enter.go", pkg)
		}
	case "plugin":
		pluginEnter := filepath.Join(uc.config.Root, uc.config.Server, "internal", "plugin", pkg, "plugin.go")
		if _, err := os.Stat(pluginEnter); err != nil {
			return fmt.Errorf("plugin结构异常,缺少internal/plugin/%s/plugin.go", pkg)
		}
	}
	return nil
}

// Create 创建生成自动化代码
func (uc *AutoCodeTemplateUsecase) Create(ctx context.Context, info *AutoCodeInfo) error {
	// 查询包信息
	autoPkg, err := uc.repo.GetPackageByName(ctx, info.Package)
	if err != nil {
		return errors.Wrap(err, "查询包失败!")
	}

	// 检查包结构
	if err = uc.checkPackage(info.Package, autoPkg.Template); err != nil {
		return err
	}

	// 检查重复创建
	if uc.repo.Repeat(ctx, info.BusinessDB, info.StructName, info.Abbreviation, info.Package) {
		return errors.New("已经创建过此数据结构,请勿重复创建!")
	}

	// 生成代码
	generate, templates, injections, err := uc.generate(ctx, info, autoPkg)
	if err != nil {
		return err
	}

	// 写入文件
	for key, builder := range generate {
		if err = os.MkdirAll(filepath.Dir(key), os.ModePerm); err != nil {
			return errors.Wrapf(err, "[filepath:%s]创建文件夹失败!", key)
		}
		if err = os.WriteFile(key, []byte(builder.String()), 0666); err != nil {
			return errors.Wrapf(err, "[filepath:%s]写入文件失败!", key)
		}
	}

	// 创建历史记录
	history := &SysAutoCodeHistory{
		Table:        info.TableName,
		Package:      info.Package,
		StructName:   info.StructName,
		Abbreviation: info.Abbreviation,
		BusinessDB:   info.BusinessDB,
		Description:  info.Description,
		Templates:    templates,
	}

	// 自动创建API
	if info.AutoCreateApiToSql && !info.OnlyTemplate {
		apis := uc.buildApis(info)
		apiIDs, err := uc.repo.CreateApis(ctx, apis)
		if err != nil {
			return err
		}
		history.ApiIDs = apiIDs
	}

	// 自动创建菜单
	if info.AutoCreateMenuToSql {
		menu, err := uc.repo.GetMenuByName(ctx, info.Abbreviation)
		if err == nil && menu != nil {
			history.MenuID = menu.ID
		} else {
			newMenu := uc.buildMenu(info, autoPkg.Template)
			if info.AutoCreateBtnAuth && !info.OnlyTemplate {
				newMenu.MenuBtn = uc.buildMenuBtns(info)
			}
			if err = uc.repo.CreateMenu(ctx, newMenu); err != nil {
				return errors.Wrap(err, "创建菜单失败!")
			}
			history.MenuID = newMenu.ID
		}
	}

	// 处理Excel导出模板
	if info.HasExcel {
		exportTpl := uc.buildExportTemplate(info)
		if err = uc.repo.CreateExportTemplate(ctx, exportTpl); err != nil {
			return err
		}
		history.ExportTemplateID = exportTpl.ID
	}

	// 保存注入信息
	history.Injections = make(map[string]string, len(injections))
	for key, value := range injections {
		bytes, _ := json.Marshal(value)
		history.Injections[key] = string(bytes)
	}

	// 创建历史记录
	return uc.historyRepo.Create(ctx, history)
}

// Preview 预览自动化代码
func (uc *AutoCodeTemplateUsecase) Preview(ctx context.Context, info *AutoCodeInfo) (map[string]string, error) {
	// 查询包信息
	entity, err := uc.repo.GetPackageByName(ctx, info.Package)
	if err != nil {
		return nil, errors.Wrap(err, "查询包失败!")
	}

	// 检查重复创建
	if uc.repo.Repeat(ctx, info.BusinessDB, info.StructName, info.Abbreviation, info.Package) && !info.IsAdd {
		return nil, errors.New("已经创建过此数据结构或重复简称,请勿重复创建!")
	}

	preview := make(map[string]string)
	codes, _, _, err := uc.generate(ctx, info, entity)
	if err != nil {
		return nil, err
	}

	for key, writer := range codes {
		if len(key) > len(uc.config.Root) {
			key, _ = filepath.Rel(uc.config.Root, key)
		}
		suffix := filepath.Ext(key)[1:]
		var builder strings.Builder
		builder.WriteString("```" + suffix + "\n\n")
		builder.WriteString(writer.String())
		builder.WriteString("\n\n```")
		preview[key] = builder.String()
	}
	return preview, nil
}

// generate 生成代码
func (uc *AutoCodeTemplateUsecase) generate(ctx context.Context, info *AutoCodeInfo, entity *SysAutoCodePackage) (map[string]strings.Builder, map[string]string, map[string]interface{}, error) {
	dataList, asts, fileList, err := uc.packageRepo.Templates(ctx, entity, info, false)
	if err != nil {
		return nil, nil, nil, err
	}

	code := make(map[string]strings.Builder)
	for templatePath := range dataList {
		// 获取目标文件路径
		targetPath, ok := fileList[templatePath]
		if !ok {
			continue
		}
		// 解析并执行模板
		files, err := template.New(filepath.Base(templatePath)).Funcs(autocode.GetTemplateFuncMap()).ParseFiles(templatePath)
		if err != nil {
			return nil, nil, nil, errors.Wrapf(err, "[filepath:%s]读取模版文件失败!", templatePath)
		}
		var builder strings.Builder
		if err = files.Execute(&builder, info); err != nil {
			return nil, nil, nil, errors.Wrapf(err, "[filepath:%s]生成文件失败!", targetPath)
		}
		code[targetPath] = builder
	}

	injections := make(map[string]interface{}, len(asts))
	for key, value := range asts {
		keys := strings.Split(key, "=>")
		if len(keys) == 2 {
			if keys[1] == TypePluginInitializeV2 {
				continue
			}
			if info.OnlyTemplate {
				if keys[1] == TypePackageInitializeGorm || keys[1] == TypePluginInitializeGorm {
					continue
				}
			}
			if !info.AutoMigrate {
				if keys[1] == TypePackageInitializeGorm || keys[1] == TypePluginInitializeGorm {
					continue
				}
			}
			var builder strings.Builder
			parse, _ := value.Parse("", &builder)
			if parse != nil {
				_ = value.Injection(parse)
				if err = value.Format("", &builder, parse); err != nil {
					return nil, nil, nil, err
				}
				code[keys[0]] = builder
				injections[keys[1]] = value
				fmt.Println(keys[0], "注入成功!")
			}
		}
	}
	return code, fileList, injections, nil
}

// AddFunc 添加函数
func (uc *AutoCodeTemplateUsecase) AddFunc(info *AutoFuncInfo) error {
	autoPkg, err := uc.packageRepo.FindByPackageName(context.Background(), info.Package)
	if err != nil {
		return err
	}
	if autoPkg.Template != "package" {
		info.IsPlugin = true
	}

	if err = uc.addTemplateToFile("api.go", info); err != nil {
		return err
	}
	if err = uc.addTemplateToFile("server.go", info); err != nil {
		return err
	}
	if err = uc.addTemplateToFile("api.js", info); err != nil {
		return err
	}
	return uc.addTemplateToAst("router", info)
}

// GetApiAndServer 获取API和Server代码
func (uc *AutoCodeTemplateUsecase) GetApiAndServer(info *AutoFuncInfo) (map[string]string, error) {
	autoPkg, err := uc.packageRepo.FindByPackageName(context.Background(), info.Package)
	if err != nil {
		return nil, err
	}
	if autoPkg.Template != "package" {
		info.IsPlugin = true
	}

	apiStr, err := uc.getTemplateStr("api.go", info)
	if err != nil {
		return nil, err
	}
	serverStr, err := uc.getTemplateStr("server.go", info)
	if err != nil {
		return nil, err
	}
	jsStr, err := uc.getTemplateStr("api.js", info)
	if err != nil {
		return nil, err
	}
	return map[string]string{"api": apiStr, "server": serverStr, "js": jsStr}, nil
}

// getTemplateStr 获取模板字符串
func (uc *AutoCodeTemplateUsecase) getTemplateStr(t string, info *AutoFuncInfo) (string, error) {
	tempPath := filepath.Join(uc.config.Root, uc.config.Server, "resource", "function", t+".tpl")
	files, err := template.New(filepath.Base(tempPath)).Funcs(autocode.GetTemplateFuncMap()).ParseFiles(tempPath)
	if err != nil {
		return "", errors.Wrapf(err, "[filepath:%s]读取模版文件失败!", tempPath)
	}
	var builder strings.Builder
	if err = files.Execute(&builder, info); err != nil {
		return "", errors.Wrapf(err, "[filepath:%s]生成文件失败!", tempPath)
	}
	return builder.String(), nil
}

// addTemplateToAst 添加模板到AST
// 支持 Kratos DDD 架构的路由注入
func (uc *AutoCodeTemplateUsecase) addTemplateToAst(t string, info *AutoFuncInfo) error {
	// Kratos DDD 架构：路由文件在 internal/server/router/{package}/
	tPath := filepath.Join(uc.config.Root, uc.config.Server, "internal", "server", "router", info.Package, info.HumpPackageName+".go")
	funcName := fmt.Sprintf("Init%sRouter", info.StructName)

	routerStr := "RouterWithoutAuth"
	if info.IsAuth {
		routerStr = "Router"
	}

	stmtStr := fmt.Sprintf("%s%s.%s(\"%s\", %sApi.%s)", info.Abbreviation, routerStr, info.Method, info.Router, info.Abbreviation, info.FuncName)
	if info.IsPlugin {
		tPath = filepath.Join(uc.config.Root, uc.config.Server, "internal", "plugin", info.Package, "router", info.HumpPackageName+".go")
		stmtStr = fmt.Sprintf("group.%s(\"%s\", api%s.%s)", info.Method, info.Router, info.StructName, info.FuncName)
		funcName = "Init"
	}

	src, err := os.ReadFile(tPath)
	if err != nil {
		return err
	}

	fileSet := token.NewFileSet()
	astFile, err := parser.ParseFile(fileSet, "", src, 0)
	if err != nil {
		return err
	}

	funcDecl := utils.FindFunction(astFile, funcName)
	stmtNode := utils.CreateStmt(stmtStr)

	if info.IsAuth {
		for i := 0; i < len(funcDecl.Body.List); i++ {
			st := funcDecl.Body.List[i]
			if blockStmt, ok := st.(*ast.BlockStmt); ok {
				blockStmt.List = append(blockStmt.List, stmtNode)
				break
			}
		}
	} else {
		for i := len(funcDecl.Body.List) - 1; i >= 0; i-- {
			st := funcDecl.Body.List[i]
			if blockStmt, ok := st.(*ast.BlockStmt); ok {
				blockStmt.List = append(blockStmt.List, stmtNode)
				break
			}
		}
	}

	f, err := os.Create(tPath)
	if err != nil {
		return err
	}
	defer f.Close()

	return format.Node(f, fileSet, astFile)
}

// addTemplateToFile 添加模板到文件
// 支持 Kratos DDD 架构的文件路径：
// - handler: internal/server/handler/{package}/
// - service: internal/service/{package}/
// - api.ts: web/src/services/kratos/
func (uc *AutoCodeTemplateUsecase) addTemplateToFile(t string, info *AutoFuncInfo) error {
	getTemplateStr, err := uc.getTemplateStr(t, info)
	if err != nil {
		return err
	}

	var target string
	switch t {
	case "api.go":
		// Kratos DDD 架构：Handler 在 internal/server/handler/{package}/
		if info.IsAi && info.ApiFunc != "" {
			getTemplateStr = info.ApiFunc
		}
		target = filepath.Join(uc.config.Root, uc.config.Server, "internal", "server", "handler", info.Package, info.HumpPackageName+".go")
	case "server.go":
		// Kratos DDD 架构：Service 在 internal/service/{package}/
		if info.IsAi && info.ServerFunc != "" {
			getTemplateStr = info.ServerFunc
		}
		target = filepath.Join(uc.config.Root, uc.config.Server, "internal", "service", info.Package, info.HumpPackageName+".go")
	case "api.js":
		// Kratos DDD 架构：前端 API 在 web/src/services/kratos/
		if info.IsAi && info.JsFunc != "" {
			getTemplateStr = info.JsFunc
		}
		target = filepath.Join(uc.config.Root, uc.config.Web, "src", "services", "kratos", info.PackageName+".ts")
	}

	if info.IsPlugin {
		switch t {
		case "api.go":
			target = filepath.Join(uc.config.Root, uc.config.Server, "internal", "plugin", info.Package, "api", info.HumpPackageName+".go")
		case "server.go":
			target = filepath.Join(uc.config.Root, uc.config.Server, "internal", "plugin", info.Package, "service", info.HumpPackageName+".go")
		case "api.js":
			target = filepath.Join(uc.config.Root, uc.config.Web, "src", "plugin", info.Package, "api", info.PackageName+".ts")
		}
	}

	file, err := os.OpenFile(target, os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		return err
	}
	defer file.Close()

	_, err = fmt.Fprintln(file, getTemplateStr)
	return err
}

// buildApis 构建API列表
func (uc *AutoCodeTemplateUsecase) buildApis(info *AutoCodeInfo) []SysApi {
	apis := []SysApi{
		{Path: "/" + info.Abbreviation + "/" + "create" + info.StructName, Description: "新增" + info.Description, ApiGroup: info.Description, Method: "POST"},
		{Path: "/" + info.Abbreviation + "/" + "delete" + info.StructName, Description: "删除" + info.Description, ApiGroup: info.Description, Method: "DELETE"},
		{Path: "/" + info.Abbreviation + "/" + "delete" + info.StructName + "ByIds", Description: "批量删除" + info.Description, ApiGroup: info.Description, Method: "DELETE"},
		{Path: "/" + info.Abbreviation + "/" + "update" + info.StructName, Description: "更新" + info.Description, ApiGroup: info.Description, Method: "PUT"},
		{Path: "/" + info.Abbreviation + "/" + "find" + info.StructName, Description: "根据ID获取" + info.Description, ApiGroup: info.Description, Method: "GET"},
		{Path: "/" + info.Abbreviation + "/" + "get" + info.StructName + "List", Description: "获取" + info.Description + "列表", ApiGroup: info.Description, Method: "GET"},
	}
	if info.HasExcel {
		apis = append(apis, []SysApi{
			{Path: "/" + info.Abbreviation + "/" + "export" + info.StructName + "Excel", Description: "导出" + info.Description + "Excel", ApiGroup: info.Description, Method: "GET"},
			{Path: "/" + info.Abbreviation + "/" + "import" + info.StructName + "Excel", Description: "导入" + info.Description + "Excel", ApiGroup: info.Description, Method: "POST"},
			{Path: "/" + info.Abbreviation + "/" + "download" + info.StructName + "Template", Description: "下载" + info.Description + "模板", ApiGroup: info.Description, Method: "GET"},
		}...)
	}
	return apis
}

// buildMenu 构建菜单
// 支持 Kratos DDD 架构的前端组件路径：
// - package: pages/{package}/{entity}/index
// - plugin: plugin/{package}/view/{entity}
func (uc *AutoCodeTemplateUsecase) buildMenu(info *AutoCodeInfo, template string) *SysBaseMenu {
	// Kratos DDD 架构：React 页面在 pages/{package}/{entity}/
	component := "pages/" + info.Package + "/" + info.PackageName + "/index"
	if template == "plugin" {
		component = "plugin/" + info.Package + "/view/" + info.PackageName
	}
	return &SysBaseMenu{
		ParentId:  0,
		Path:      info.Abbreviation,
		Name:      info.Abbreviation,
		Hidden:    false,
		Component: component,
		Sort:      0,
		Meta: Meta{
			Title: info.Description,
			Icon:  "menu",
		},
	}
}

// buildMenuBtns 构建菜单按钮
func (uc *AutoCodeTemplateUsecase) buildMenuBtns(info *AutoCodeInfo) []SysBaseMenuBtn {
	btns := []SysBaseMenuBtn{
		{Name: "add", Desc: "新增"},
		{Name: "batchDelete", Desc: "批量删除"},
		{Name: "delete", Desc: "删除"},
		{Name: "edit", Desc: "编辑"},
		{Name: "info", Desc: "详情"},
	}
	if info.HasExcel {
		btns = append(btns, []SysBaseMenuBtn{
			{Name: "exportTemplate", Desc: "导出模板"},
			{Name: "exportExcel", Desc: "导出Excel"},
			{Name: "importExcel", Desc: "导入Excel"},
		}...)
	}
	return btns
}

// buildExportTemplate 构建导出模板
func (uc *AutoCodeTemplateUsecase) buildExportTemplate(info *AutoCodeInfo) *SysExportTemplate {
	fieldsMap := make(map[string]string, len(info.Fields))
	for _, field := range info.Fields {
		if field.Excel {
			fieldsMap[field.ColumnName] = field.FieldDesc
		}
	}
	templateInfo, _ := json.Marshal(fieldsMap)
	return &SysExportTemplate{
		DBName:       info.BusinessDB,
		Name:         info.Package + "_" + info.StructName,
		Table:        info.TableName,
		TemplateID:   info.Package + "_" + info.StructName,
		TemplateInfo: string(templateInfo),
	}
}

// AST类型常量
const (
	TypePackageApiEnter         = "PackageApiEnter"
	TypePackageRouterEnter      = "PackageRouterEnter"
	TypePackageServiceEnter     = "PackageServiceEnter"
	TypePackageInitializeGorm   = "PackageInitializeGorm"
	TypePackageInitializeRouter = "PackageInitializeRouter"
	TypePackageGormGen          = "PackageGormGen"
	TypePluginGen               = "PluginGen"
	TypePluginApiEnter          = "PluginApiEnter"
	TypePluginInitializeV2      = "PluginInitializeV2"
	TypePluginRouterEnter       = "PluginRouterEnter"
	TypePluginServiceEnter      = "PluginServiceEnter"
	TypePluginInitializeGorm    = "PluginInitializeGorm"
	TypePluginInitializeRouter  = "PluginInitializeRouter"
)

// AutoCodeInfo 相关实体类型
type AutoCodeInfo struct {
	Package             string
	PackageT            string
	TableName           string
	BusinessDB          string
	StructName          string
	PackageName         string
	Description         string
	Abbreviation        string
	HumpPackageName     string
	GvaModel            bool
	AutoMigrate         bool
	AutoCreateResource  bool
	AutoCreateApiToSql  bool
	AutoCreateMenuToSql bool
	AutoCreateBtnAuth   bool
	OnlyTemplate        bool
	IsTree              bool
	TreeJson            string
	IsAdd               bool
	Fields              []*AutoCodeField
	GenerateWeb         bool
	GenerateServer      bool
	Module              string
	DictTypes           []string
	PrimaryField        *AutoCodeField
	DataSourceMap       map[string]*DataSource
	HasPic              bool
	HasFile             bool
	HasTimer            bool
	NeedSort            bool
	NeedJSON            bool
	HasRichText         bool
	HasDataSource       bool
	HasSearchTimer      bool
	HasArray            bool
	HasExcel            bool
	CustomMethods       []*CustomMethod // 自定义查询方法
	HasCustomMethods    bool            // 是否有自定义查询方法
}

// CustomMethod 自定义查询方法
// 用于在 GORM Gen 生成的代码中添加自定义查询方法
type CustomMethod struct {
	Name        string               `json:"name"`        // 方法名称 (如: FindByName, GetActiveUsers)
	Description string               `json:"description"` // 方法描述
	ReturnType  string               `json:"returnType"`  // 返回类型: single(单个), list(列表), count(计数), exists(存在检查)
	Params      []*CustomMethodParam `json:"params"`      // 方法参数
	Conditions  []*CustomCondition   `json:"conditions"`  // 查询条件
	OrderBy     string               `json:"orderBy"`     // 排序字段 (如: created_at DESC)
	Limit       int                  `json:"limit"`       // 限制数量 (0表示不限制)
}

// CustomMethodParam 自定义方法参数
type CustomMethodParam struct {
	Name      string `json:"name"`      // 参数名称
	Type      string `json:"type"`      // 参数类型 (string, int, uint, bool, time.Time等)
	FieldName string `json:"fieldName"` // 对应的字段名 (用于生成查询条件)
}

// CustomCondition 自定义查询条件
type CustomCondition struct {
	FieldName string `json:"fieldName"` // 字段名
	Operator  string `json:"operator"`  // 操作符: eq, neq, gt, gte, lt, lte, like, in, between, isNull, isNotNull
	ParamName string `json:"paramName"` // 参数名 (对应 CustomMethodParam.Name)
}

// DataSource 数据源
type DataSource struct {
	DBName       string `json:"dbName"`
	Table        string `json:"table"`
	Label        string `json:"label"`
	Value        string `json:"value"`
	Association  int    `json:"association"`
	HasDeletedAt bool   `json:"hasDeletedAt"`
}

// AutoCodeField 自动代码字段
type AutoCodeField struct {
	FieldName       string      `json:"fieldName"`
	FieldDesc       string      `json:"fieldDesc"`
	FieldType       string      `json:"fieldType"`
	FieldJson       string      `json:"fieldJson"`
	DataTypeLong    string      `json:"dataTypeLong"`
	Comment         string      `json:"comment"`
	ColumnName      string      `json:"columnName"`
	FieldSearchType string      `json:"fieldSearchType"`
	FieldSearchHide bool        `json:"fieldSearchHide"`
	DictType        string      `json:"dictType"`
	Form            bool        `json:"form"`
	Table           bool        `json:"table"`
	Desc            bool        `json:"desc"`
	Excel           bool        `json:"excel"`
	Require         bool        `json:"require"`
	DefaultValue    string      `json:"defaultValue"`
	ErrorText       string      `json:"errorText"`
	Clearable       bool        `json:"clearable"`
	Sort            bool        `json:"sort"`
	PrimaryKey      bool        `json:"primaryKey"`
	DataSource      *DataSource `json:"dataSource"`
	CheckDataSource bool        `json:"checkDataSource"`
	FieldIndexType  string      `json:"fieldIndexType"`
}

// AutoFuncInfo 自动函数信息
type AutoFuncInfo struct {
	Package         string
	FuncName        string
	Router          string
	FuncDesc        string
	BusinessDB      string
	StructName      string
	PackageName     string
	Description     string
	Abbreviation    string
	HumpPackageName string
	Method          string
	IsPlugin        bool
	IsAuth          bool
	IsPreview       bool
	IsAi            bool
	ApiFunc         string
	ServerFunc      string
	JsFunc          string
}

// SysExportTemplate 导出模板
type SysExportTemplate struct {
	ID           uint   `json:"ID" gorm:"primarykey"`
	DBName       string `json:"dbName" gorm:"column:db_name;comment:数据库名"`
	Name         string `json:"name" gorm:"column:name;comment:模板名称"`
	Table        string `json:"tableName" gorm:"column:table_name;comment:表名"`
	TemplateID   string `json:"templateId" gorm:"column:template_id;comment:模板ID"`
	TemplateInfo string `json:"templateInfo" gorm:"column:template_info;type:text;comment:模板信息"`
}

func (SysExportTemplate) TableName() string {
	return "sys_export_templates"
}
