package handler

import (
	"kra/internal/service"
	"kra/internal/service/dto"
	"strconv"

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

type Dictionary struct{ service *service.DictionaryService }

func NewDictionary(service *service.DictionaryService) *Dictionary {
	return &Dictionary{service: service}
}

func (h *Dictionary) Create(c *gin.Context) {
	var req dto.DictionaryRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	created, err := h.service.CreateDictionaryRequest(c.Request.Context(), &req)
	if err != nil {
		Fail(c, "创建失败")
		return
	}
	Write(c, CodeSuccess, created, "创建成功")
}
func (h *Dictionary) Update(c *gin.Context) {
	var req dto.DictionaryRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if err := h.service.UpdateDictionaryRequest(c.Request.Context(), &req); err != nil {
		Fail(c, "更新失败")
		return
	}
	Write(c, CodeSuccess, gin.H{}, "更新成功")
}
func (h *Dictionary) Delete(c *gin.Context) {
	var req dto.DictionaryRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if err := h.service.DeleteDictionary(c.Request.Context(), req.ID); err != nil {
		Fail(c, "删除失败")
		return
	}
	Write(c, CodeSuccess, gin.H{}, "删除成功")
}
func (h *Dictionary) Find(c *gin.Context) {
	var req dto.DictionaryRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	item, err := h.service.Dictionary(c.Request.Context(), req.ID, req.Type, req.Status, true)
	if err != nil {
		Fail(c, "字典未创建或未开启")
		return
	}
	Write(c, CodeSuccess, gin.H{"resysDictionary": item}, "查询成功")
}
func (h *Dictionary) List(details bool) gin.HandlerFunc {
	return func(c *gin.Context) {
		items, _, err := h.service.Dictionaries(c.Request.Context(), 0, 0, c.Query("name"), "", details)
		if err != nil {
			Fail(c, "获取失败")
			return
		}
		Write(c, CodeSuccess, items, "获取成功")
	}
}
func (h *Dictionary) Export(c *gin.Context) {
	var req dto.DictionaryRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if req.ID == 0 {
		Fail(c, "字典ID不能为空")
		return
	}
	item, err := h.service.ExportDictionary(c.Request.Context(), req.ID)
	if err != nil {
		Fail(c, "导出失败")
		return
	}
	Write(c, CodeSuccess, item, "导出成功")
}
func (h *Dictionary) Import(c *gin.Context) {
	var req dto.ImportDictionaryRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if err := h.service.ImportDictionaryJSON(c.Request.Context(), req.JSON); err != nil {
		Fail(c, "导入失败: "+err.Error())
		return
	}
	Write(c, CodeSuccess, gin.H{}, "导入成功")
}

func (h *Dictionary) CreateDetail(c *gin.Context) {
	var req dto.DictionaryDetailRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if err := h.service.CreateDictionaryDetailRequest(c.Request.Context(), &req); err != nil {
		Fail(c, "创建失败")
		return
	}
	Write(c, CodeSuccess, gin.H{}, "创建成功")
}
func (h *Dictionary) UpdateDetail(c *gin.Context) {
	var req dto.DictionaryDetailRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if err := h.service.UpdateDictionaryDetailRequest(c.Request.Context(), &req); err != nil {
		Fail(c, "更新失败")
		return
	}
	Write(c, CodeSuccess, gin.H{}, "更新成功")
}
func (h *Dictionary) DeleteDetail(c *gin.Context) {
	var req dto.DictionaryDetailRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if err := h.service.DeleteDictionaryDetail(c.Request.Context(), req.ID); err != nil {
		Fail(c, "删除失败")
		return
	}
	Write(c, CodeSuccess, gin.H{}, "删除成功")
}
func (h *Dictionary) FindDetail(c *gin.Context) {
	var req dto.DictionaryDetailRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if req.ID == 0 {
		Fail(c, "ID值不能为空")
		return
	}
	item, err := h.service.DictionaryDetail(c.Request.Context(), req.ID)
	if err != nil {
		Fail(c, "查询失败")
		return
	}
	Write(c, CodeSuccess, gin.H{"reSysDictionaryDetail": item}, "查询成功")
}
func (h *Dictionary) Details(c *gin.Context) {
	p, size, err := page(c)
	if err != nil {
		Fail(c, err.Error())
		return
	}
	var dictionaryID uint64
	if raw, exists := c.GetQuery("sysDictionaryID"); exists && raw != "" {
		var parseErr error
		dictionaryID, parseErr = strconv.ParseUint(raw, 10, 0)
		if parseErr != nil {
			Fail(c, parseErr.Error())
			return
		}
	}
	filter := dto.DictionaryDetailListRequest{DictionaryID: uint(dictionaryID), Label: c.Query("label"), Value: c.Query("value")}
	if raw, exists := c.GetQuery("status"); exists {
		value, parseErr := strconv.ParseBool(raw)
		if parseErr != nil {
			Fail(c, parseErr.Error())
			return
		}
		filter.Status = &value
	}
	if raw, exists := c.GetQuery("parentID"); exists {
		value, parseErr := strconv.ParseUint(raw, 10, 64)
		if parseErr != nil {
			Fail(c, parseErr.Error())
			return
		}
		parentID := uint(value)
		filter.ParentID = &parentID
	}
	if raw, exists := c.GetQuery("level"); exists {
		value, parseErr := strconv.Atoi(raw)
		if parseErr != nil {
			Fail(c, parseErr.Error())
			return
		}
		filter.Level = &value
	}
	items, total, err := h.service.DictionaryDetailsRequest(c.Request.Context(), p, size, filter)
	if err != nil {
		Fail(c, "获取失败")
		return
	}
	Write(c, CodeSuccess, PageResult{List: items, Total: total, Page: p, PageSize: size}, "获取成功")
}
func (h *Dictionary) Tree(byType bool) gin.HandlerFunc {
	return func(c *gin.Context) {
		rawID := c.Query("sysDictionaryID")
		id, parseErr := strconv.ParseUint(rawID, 10, 32)
		typ := ""
		if byType {
			typ = c.Query("type")
			if typ == "" {
				Fail(c, "字典类型不能为空")
				return
			}
		} else if rawID == "" {
			Fail(c, "字典ID不能为空")
			return
		} else if parseErr != nil {
			Fail(c, "字典ID格式错误")
			return
		}
		items, err := h.service.DictionaryTree(c.Request.Context(), uint(id), typ)
		if err != nil {
			Fail(c, "获取失败")
			return
		}
		Write(c, CodeSuccess, gin.H{"list": items}, "获取成功")
	}
}
func (h *Dictionary) DetailsByParent(c *gin.Context) {
	var req dto.DictionaryDetailsByParentRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	items, err := h.service.DictionaryDetailsByParent(c.Request.Context(), req.DictionaryID, req.ParentID, req.IncludeChildren)
	if err != nil {
		Fail(c, "获取失败")
		return
	}
	Write(c, CodeSuccess, gin.H{"list": items}, "获取成功")
}
func (h *Dictionary) Path(c *gin.Context) {
	rawID := c.Query("id")
	if rawID == "" {
		Fail(c, "字典详情ID不能为空")
		return
	}
	id, parseErr := strconv.ParseUint(rawID, 10, 32)
	if parseErr != nil {
		Fail(c, "字典详情ID格式错误")
		return
	}
	path, err := h.service.DictionaryPath(c.Request.Context(), uint(id))
	if err != nil {
		Fail(c, "获取失败")
		return
	}
	Write(c, CodeSuccess, gin.H{"path": path}, "获取成功")
}
