package system

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"time"

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

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

type VersionApi struct{}

// VersionSearchRequest 版本搜索请求
type VersionSearchRequest struct {
	Page           int         `json:"page" form:"page"`
	PageSize       int         `json:"pageSize" form:"pageSize"`
	VersionName    *string     `json:"versionName" form:"versionName"`
	VersionCode    *string     `json:"versionCode" form:"versionCode"`
	CreatedAtRange []time.Time `json:"createdAtRange" form:"createdAtRange[]"`
}

// ExportVersionRequest 导出版本请求
type ExportVersionRequest struct {
	VersionName string `json:"versionName" binding:"required"`
	VersionCode string `json:"versionCode" binding:"required"`
	Description string `json:"description"`
	MenuIds     []uint `json:"menuIds"`
	ApiIds      []uint `json:"apiIds"`
	DictIds     []uint `json:"dictIds"`
}

// VersionInfo 版本信息
type VersionInfo struct {
	Name        string `json:"name"`
	Code        string `json:"code"`
	Description string `json:"description"`
	ExportTime  string `json:"exportTime"`
}

// ExportVersionResponse 导出版本响应
type ExportVersionResponse struct {
	Version      VersionInfo              `json:"version"`
	Menus        []map[string]interface{} `json:"menus"`
	Apis         []map[string]interface{} `json:"apis"`
	Dictionaries []map[string]interface{} `json:"dictionaries"`
}

// DeleteSysVersion
// @Tags      SysVersion
// @Summary   删除版本
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     ID    query     string                         true  "版本ID"
// @Success   200   {object}  response.Response{msg=string}  "删除版本"
// @Router    /sysVersion/deleteSysVersion [delete]
func (v *VersionApi) DeleteSysVersion(c *gin.Context) {
	id := c.Query("ID")
	if id == "" {
		response.FailWithMessage("缺少参数: ID", c)
		return
	}

	if err := versionUsecase.DeleteSysVersion(c.Request.Context(), id); err != nil {
		response.FailWithMessage("删除失败:"+err.Error(), c)
		return
	}
	response.OkWithMessage("删除成功", c)
}

// DeleteSysVersionByIds
// @Tags      SysVersion
// @Summary   批量删除版本
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     IDs[]  query     []string                       true  "版本ID列表"
// @Success   200    {object}  response.Response{msg=string}  "批量删除版本"
// @Router    /sysVersion/deleteSysVersionByIds [delete]
func (v *VersionApi) DeleteSysVersionByIds(c *gin.Context) {
	ids := c.QueryArray("IDs[]")
	if len(ids) == 0 {
		response.FailWithMessage("缺少参数: IDs", c)
		return
	}

	if err := versionUsecase.DeleteSysVersionByIds(c.Request.Context(), ids); err != nil {
		response.FailWithMessage("批量删除失败:"+err.Error(), c)
		return
	}
	response.OkWithMessage("批量删除成功", c)
}

// FindSysVersion
// @Tags      SysVersion
// @Summary   根据ID获取版本
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     ID    query     string                                                     true  "版本ID"
// @Success   200   {object}  response.Response{data=map[string]interface{},msg=string}  "获取版本"
// @Router    /sysVersion/findSysVersion [get]
func (v *VersionApi) FindSysVersion(c *gin.Context) {
	id := c.Query("ID")
	if id == "" {
		response.FailWithMessage("缺少参数: ID", c)
		return
	}

	version, err := versionUsecase.GetSysVersion(c.Request.Context(), id)
	if err != nil {
		response.FailWithMessage("查询失败:"+err.Error(), c)
		return
	}
	response.OkWithData(toVersionResponse(version), c)
}

// GetSysVersionList
// @Tags      SysVersion
// @Summary   分页获取版本列表
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  query     VersionSearchRequest                                    true  "页码, 每页大小, 搜索条件"
// @Success   200   {object}  response.Response{data=response.PageResult,msg=string}  "分页获取版本列表,返回包括列表,总数,页码,每页数量"
// @Router    /sysVersion/getSysVersionList [get]
func (v *VersionApi) GetSysVersionList(c *gin.Context) {
	var req VersionSearchRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	if req.Page == 0 {
		req.Page = 1
	}
	if req.PageSize == 0 {
		req.PageSize = 10
	}

	searchReq := &system.VersionSearchReq{
		Page:           req.Page,
		PageSize:       req.PageSize,
		VersionName:    req.VersionName,
		VersionCode:    req.VersionCode,
		CreatedAtRange: req.CreatedAtRange,
	}

	list, total, err := versionUsecase.GetSysVersionInfoList(c.Request.Context(), searchReq)
	if err != nil {
		response.FailWithMessage("获取失败:"+err.Error(), c)
		return
	}

	result := make([]map[string]interface{}, len(list))
	for i, item := range list {
		result[i] = toVersionResponse(item)
	}

	response.OkWithDetailed(response.PageResult{
		List:     result,
		Total:    total,
		Page:     req.Page,
		PageSize: req.PageSize,
	}, "获取成功", c)
}

// GetSysVersionPublic
// @Tags      SysVersion
// @Summary   公开版本接口
// @Produce   application/json
// @Success   200  {object}  response.Response{data=map[string]interface{},msg=string}  "获取公开版本信息"
// @Router    /sysVersion/getSysVersionPublic [get]
func (v *VersionApi) GetSysVersionPublic(c *gin.Context) {
	response.OkWithDetailed(gin.H{
		"info": "不需要鉴权的版本管理接口信息",
	}, "获取成功", c)
}

// ExportVersion
// @Tags      SysVersion
// @Summary   创建发版数据
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      ExportVersionRequest           true  "发版数据"
// @Success   200   {object}  response.Response{msg=string}  "创建发版成功"
// @Router    /sysVersion/exportVersion [post]
func (v *VersionApi) ExportVersion(c *gin.Context) {
	var req ExportVersionRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	ctx := c.Request.Context()

	// 获取选中的菜单数据
	var menuData []map[string]interface{}
	if len(req.MenuIds) > 0 {
		menus, err := versionUsecase.GetMenusByIds(ctx, req.MenuIds)
		if err != nil {
			response.FailWithMessage("获取菜单数据失败:"+err.Error(), c)
			return
		}
		for _, m := range menus {
			menuData = append(menuData, map[string]interface{}{
				"path":      m.Path,
				"name":      m.Name,
				"hidden":    m.Hidden,
				"component": m.Component,
				"sort":      m.Sort,
			})
		}
	}

	// 获取选中的API数据
	var apiData []map[string]interface{}
	if len(req.ApiIds) > 0 {
		apis, err := versionUsecase.GetApisByIds(ctx, req.ApiIds)
		if err != nil {
			response.FailWithMessage("获取API数据失败:"+err.Error(), c)
			return
		}
		for _, a := range apis {
			apiData = append(apiData, map[string]interface{}{
				"path":        a.Path,
				"description": a.Description,
				"apiGroup":    a.ApiGroup,
				"method":      a.Method,
			})
		}
	}

	// 获取选中的字典数据
	var dictData []map[string]interface{}
	if len(req.DictIds) > 0 {
		dicts, err := versionUsecase.GetDictionariesByIds(ctx, req.DictIds)
		if err != nil {
			response.FailWithMessage("获取字典数据失败:"+err.Error(), c)
			return
		}
		for _, d := range dicts {
			dictData = append(dictData, map[string]interface{}{
				"name":   d.Name,
				"type":   d.Type,
				"status": d.Status,
				"desc":   d.Desc,
			})
		}
	}

	// 构建导出数据
	exportData := ExportVersionResponse{
		Version: VersionInfo{
			Name:        req.VersionName,
			Code:        req.VersionCode,
			Description: req.Description,
			ExportTime:  time.Now().Format("2006-01-02 15:04:05"),
		},
		Menus:        menuData,
		Apis:         apiData,
		Dictionaries: dictData,
	}

	// 转换为JSON
	jsonData, err := json.MarshalIndent(exportData, "", "  ")
	if err != nil {
		response.FailWithMessage("JSON序列化失败:"+err.Error(), c)
		return
	}

	// 保存版本记录
	version := &system.SysVersion{
		VersionName: req.VersionName,
		VersionCode: req.VersionCode,
		Description: req.Description,
		VersionData: string(jsonData),
	}

	if err := versionUsecase.CreateSysVersion(ctx, version); err != nil {
		response.FailWithMessage("保存版本记录失败:"+err.Error(), c)
		return
	}

	response.OkWithMessage("创建发版成功", c)
}

// DownloadVersionJson
// @Tags      SysVersion
// @Summary   下载版本JSON数据
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     ID    query     string  true  "版本ID"
// @Success   200   {file}    json    "版本JSON文件"
// @Router    /sysVersion/downloadVersionJson [get]
func (v *VersionApi) DownloadVersionJson(c *gin.Context) {
	id := c.Query("ID")
	if id == "" {
		response.FailWithMessage("版本ID不能为空", c)
		return
	}

	version, err := versionUsecase.GetSysVersion(c.Request.Context(), id)
	if err != nil {
		response.FailWithMessage("获取版本记录失败:"+err.Error(), c)
		return
	}

	var jsonData []byte
	if version.VersionData != "" {
		jsonData = []byte(version.VersionData)
	} else {
		basicData := ExportVersionResponse{
			Version: VersionInfo{
				Name:        version.VersionName,
				Code:        version.VersionCode,
				Description: version.Description,
				ExportTime:  version.CreatedAt.Format("2006-01-02 15:04:05"),
			},
		}
		jsonData, _ = json.MarshalIndent(basicData, "", "  ")
	}

	filename := fmt.Sprintf("version_%s_%s.json", version.VersionCode, time.Now().Format("20060102150405"))
	c.Header("Content-Type", "application/json")
	c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
	c.Header("Content-Length", strconv.Itoa(len(jsonData)))

	c.Data(http.StatusOK, "application/json", jsonData)
}

// ImportVersion
// @Tags      SysVersion
// @Summary   导入版本数据
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      map[string]interface{}         true  "版本JSON数据"
// @Success   200   {object}  response.Response{msg=string}  "导入成功"
// @Router    /sysVersion/importVersion [post]
func (v *VersionApi) ImportVersion(c *gin.Context) {
	var importData map[string]interface{}
	if err := c.ShouldBindJSON(&importData); err != nil {
		response.FailWithMessage("解析JSON数据失败:"+err.Error(), c)
		return
	}

	// 验证数据格式
	versionInfo, ok := importData["version"].(map[string]interface{})
	if !ok {
		response.FailWithMessage("版本信息格式错误", c)
		return
	}

	name, _ := versionInfo["name"].(string)
	code, _ := versionInfo["code"].(string)
	desc, _ := versionInfo["description"].(string)

	if name == "" || code == "" {
		response.FailWithMessage("版本名称和版本号不能为空", c)
		return
	}

	// 创建导入记录
	jsonData, _ := json.Marshal(importData)
	version := &system.SysVersion{
		VersionName: name,
		VersionCode: fmt.Sprintf("%s_imported_%s", code, time.Now().Format("20060102150405")),
		Description: fmt.Sprintf("导入版本: %s", desc),
		VersionData: string(jsonData),
	}

	if err := versionUsecase.CreateSysVersion(c.Request.Context(), version); err != nil {
		response.FailWithMessage("保存导入记录失败:"+err.Error(), c)
		return
	}

	response.OkWithMessage("导入成功", c)
}

// toVersionResponse 转换版本响应
func toVersionResponse(v *system.SysVersion) map[string]interface{} {
	return map[string]interface{}{
		"id":          v.ID,
		"versionName": v.VersionName,
		"versionCode": v.VersionCode,
		"description": v.Description,
		"versionData": v.VersionData,
		"createdAt":   v.CreatedAt,
		"updatedAt":   v.UpdatedAt,
	}
}
