package system

import (
	"go/token"
	"strings"

	"kra/internal/biz/system"
	"kra/pkg/response"
	"kra/pkg/utils"

	"github.com/gin-gonic/gin"
)

// Preview 预览创建后的代码
// @Tags      AutoCodeTemplate
// @Summary   预览创建后的代码
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      system.AutoCodeInfo  true  "预览创建代码"
// @Success   200   {object}  response.Response{data=map[string]interface{},msg=string}  "预览创建后的代码"
// @Router    /autoCode/preview [post]
func (a *AutoCodeTemplateApi) Preview(c *gin.Context) {
	var info system.AutoCodeInfo
	if err := c.ShouldBindJSON(&info); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if err := utils.Verify(info, utils.AutoCodeVerify); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if err := pretreatment(&info); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	info.PackageT = utils.FirstUpper(info.Package)
	autoCode, err := autoCodeTemplateUsecase.Preview(c.Request.Context(), &info)
	if err != nil {
		response.FailWithMessage("预览失败:"+err.Error(), c)
		return
	}
	response.OkWithDetailed(gin.H{"autoCode": autoCode}, "预览成功", c)
}

// Create 自动代码模板
// @Tags      AutoCodeTemplate
// @Summary   自动代码模板
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      system.AutoCodeInfo  true  "创建自动代码"
// @Success   200   {object}  response.Response{msg=string}  "创建成功"
// @Router    /autoCode/createTemp [post]
func (a *AutoCodeTemplateApi) Create(c *gin.Context) {
	var info system.AutoCodeInfo
	if err := c.ShouldBindJSON(&info); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if err := utils.Verify(info, utils.AutoCodeVerify); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if err := pretreatment(&info); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if err := autoCodeTemplateUsecase.Create(c.Request.Context(), &info); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	response.OkWithMessage("创建成功", c)
}

// AddFunc 增加方法
// @Tags      AutoCodeTemplate
// @Summary   增加方法
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      system.AutoFuncInfo  true  "增加方法"
// @Success   200   {object}  response.Response{msg=string}  "注入成功"
// @Router    /autoCode/addFunc [post]
func (a *AutoCodeTemplateApi) AddFunc(c *gin.Context) {
	var info system.AutoFuncInfo
	if err := c.ShouldBindJSON(&info); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	var tempMap map[string]string
	var err error
	if info.IsPreview {
		info.Router = "填充router"
		info.FuncName = "填充funcName"
		info.Method = "填充method"
		info.Description = "填充description"
		tempMap, err = autoCodeTemplateUsecase.GetApiAndServer(&info)
	} else {
		err = autoCodeTemplateUsecase.AddFunc(&info)
	}
	if err != nil {
		response.FailWithMessage("注入失败: "+err.Error(), c)
		return
	}
	if info.IsPreview {
		response.OkWithDetailed(tempMap, "注入成功", c)
		return
	}
	response.OkWithMessage("注入成功", c)
}

// pretreatment 预处理AutoCodeInfo
func pretreatment(r *system.AutoCodeInfo) error {
	// 处理Go关键字
	if token.IsKeyword(r.Abbreviation) {
		r.Abbreviation = r.Abbreviation + "_"
	}
	// 处理test后缀
	if strings.HasSuffix(r.HumpPackageName, "test") {
		r.HumpPackageName = r.HumpPackageName + "_"
	}

	length := len(r.Fields)
	dict := make(map[string]string, length)
	r.DataSourceMap = make(map[string]*system.DataSource, length)

	for i := 0; i < length; i++ {
		if r.Fields[i].Excel {
			r.HasExcel = true
		}
		if r.Fields[i].DictType != "" {
			dict[r.Fields[i].DictType] = ""
		}
		if r.Fields[i].Sort {
			r.NeedSort = true
		}
		switch r.Fields[i].FieldType {
		case "file":
			r.HasFile = true
			r.NeedJSON = true
		case "json":
			r.NeedJSON = true
		case "array":
			r.NeedJSON = true
			r.HasArray = true
		case "video":
			r.HasPic = true
		case "richtext":
			r.HasRichText = true
		case "picture":
			r.HasPic = true
		case "pictures":
			r.HasPic = true
			r.NeedJSON = true
		case "time.Time":
			r.HasTimer = true
			if r.Fields[i].FieldSearchType != "" && r.Fields[i].FieldSearchType != "BETWEEN" && r.Fields[i].FieldSearchType != "NOT BETWEEN" {
				r.HasSearchTimer = true
			}
		}
		if r.Fields[i].DataSource != nil {
			if r.Fields[i].DataSource.Table != "" && r.Fields[i].DataSource.Label != "" && r.Fields[i].DataSource.Value != "" {
				r.HasDataSource = true
				r.Fields[i].CheckDataSource = true
				r.DataSourceMap[r.Fields[i].FieldJson] = r.Fields[i].DataSource
			}
		}
		if !r.GvaModel && r.PrimaryField == nil && r.Fields[i].PrimaryKey {
			r.PrimaryField = r.Fields[i]
		}
	}

	// 收集字典类型
	for key := range dict {
		r.DictTypes = append(r.DictTypes, key)
	}

	// 处理默认Model（GvaModel字段名保留以兼容前端API）
	if r.GvaModel {
		r.PrimaryField = &system.AutoCodeField{
			FieldName:    "ID",
			FieldType:    "uint",
			FieldDesc:    "ID",
			FieldJson:    "ID",
			DataTypeLong: "20",
			Comment:      "主键ID",
			ColumnName:   "id",
		}
	}

	// 新增字段模式下不关注主键
	if r.IsAdd && r.PrimaryField == nil {
		r.PrimaryField = new(system.AutoCodeField)
	}

	// Package首字母大写
	if r.Package != "" {
		packages := []rune(r.Package)
		if len(packages) > 0 {
			if packages[0] >= 97 && packages[0] <= 122 {
				packages[0] = packages[0] - 32
			}
			r.PackageT = string(packages)
		}
	}

	return nil
}
