package system

import (
	"context"
	"fmt"

	"kra/internal/biz/system"

	"github.com/go-kratos/kratos/v2/errors"
	"github.com/go-kratos/kratos/v2/transport/http"
)

// DictionaryService 字典服务
type DictionaryService struct {
	uc *system.DictionaryUsecase
}

// NewDictionaryService 创建字典服务
func NewDictionaryService(uc *system.DictionaryUsecase) *DictionaryService {
	return &DictionaryService{uc: uc}
}

// DictionaryInfo 字典信息
type DictionaryInfo struct {
	ID       uint              `json:"ID"`
	Name     string            `json:"name"`
	Type     string            `json:"type"`
	Status   *bool             `json:"status"`
	Desc     string            `json:"desc"`
	ParentID *uint             `json:"parentId,omitempty"`
	Children []*DictionaryInfo `json:"children,omitempty"`
}

// DictionaryDetailInfo 字典详情信息
type DictionaryDetailInfo struct {
	ID              uint                    `json:"ID"`
	Label           string                  `json:"label"`
	Value           string                  `json:"value"`
	Extend          string                  `json:"extend"`
	Status          *bool                   `json:"status"`
	Sort            int                     `json:"sort"`
	SysDictionaryID uint                    `json:"sysDictionaryID"`
	ParentID        *uint                   `json:"parentId,omitempty"`
	Level           int                     `json:"level"`
	Path            string                  `json:"path"`
	Disabled        bool                    `json:"disabled"`
	Children        []*DictionaryDetailInfo `json:"children,omitempty"`
}

// CreateDictionaryRequest 创建字典请求
type CreateDictionaryRequest struct {
	Name     string `json:"name"`
	Type     string `json:"type"`
	Status   *bool  `json:"status"`
	Desc     string `json:"desc"`
	ParentID *uint  `json:"parentId"`
}

// CreateDictionary 创建字典
func (s *DictionaryService) CreateDictionary(ctx context.Context, req *CreateDictionaryRequest) error {
	dict := &system.Dictionary{
		Name:     req.Name,
		Type:     req.Type,
		Status:   req.Status,
		Desc:     req.Desc,
		ParentID: req.ParentID,
	}
	return s.uc.CreateDictionary(ctx, dict)
}

// UpdateDictionaryRequest 更新字典请求
type UpdateDictionaryRequest struct {
	ID       uint   `json:"ID"`
	Name     string `json:"name"`
	Type     string `json:"type"`
	Status   *bool  `json:"status"`
	Desc     string `json:"desc"`
	ParentID *uint  `json:"parentId"`
}

// UpdateDictionary 更新字典
func (s *DictionaryService) UpdateDictionary(ctx context.Context, req *UpdateDictionaryRequest) error {
	dict := &system.Dictionary{
		ID:       req.ID,
		Name:     req.Name,
		Type:     req.Type,
		Status:   req.Status,
		Desc:     req.Desc,
		ParentID: req.ParentID,
	}
	return s.uc.UpdateDictionary(ctx, dict)
}

// DeleteDictionary 删除字典
func (s *DictionaryService) DeleteDictionary(ctx context.Context, id uint) error {
	return s.uc.DeleteDictionary(ctx, id)
}

// GetDictionaryRequest 获取字典请求
type GetDictionaryRequest struct {
	Type   string `json:"type"`
	ID     uint   `json:"ID"`
	Status *bool  `json:"status"`
}

// GetDictionary 获取字典
func (s *DictionaryService) GetDictionary(ctx context.Context, req *GetDictionaryRequest) (*DictionaryInfo, error) {
	dict, err := s.uc.GetDictionary(ctx, req.Type, req.ID, req.Status)
	if err != nil {
		return nil, err
	}
	return toDictionaryInfo(dict), nil
}

// GetDictionaryListRequest 获取字典列表请求
type GetDictionaryListRequest struct {
	Name string `json:"name"`
}

// GetDictionaryList 获取字典列表
func (s *DictionaryService) GetDictionaryList(ctx context.Context, req *GetDictionaryListRequest) ([]*DictionaryInfo, error) {
	list, err := s.uc.GetDictionaryList(ctx, req.Name)
	if err != nil {
		return nil, err
	}
	result := make([]*DictionaryInfo, len(list))
	for i, d := range list {
		result[i] = toDictionaryInfo(d)
	}
	return result, nil
}

// ExportDictionary 导出字典
func (s *DictionaryService) ExportDictionary(ctx context.Context, id uint) (map[string]interface{}, error) {
	return s.uc.ExportDictionary(ctx, id)
}

// ImportDictionaryRequest 导入字典请求
type ImportDictionaryRequest struct {
	JsonStr string `json:"jsonStr"`
}

// ImportDictionary 导入字典
func (s *DictionaryService) ImportDictionary(ctx context.Context, req *ImportDictionaryRequest) error {
	return s.uc.ImportDictionary(ctx, req.JsonStr)
}

// CreateDictionaryDetailRequest 创建字典详情请求
type CreateDictionaryDetailRequest struct {
	Label           string `json:"label"`
	Value           string `json:"value"`
	Extend          string `json:"extend"`
	Status          *bool  `json:"status"`
	Sort            int    `json:"sort"`
	SysDictionaryID uint   `json:"sysDictionaryID"`
	ParentID        *uint  `json:"parentId"`
}

// CreateDictionaryDetail 创建字典详情
func (s *DictionaryService) CreateDictionaryDetail(ctx context.Context, req *CreateDictionaryDetailRequest) error {
	detail := &system.DictionaryDetail{
		Label:           req.Label,
		Value:           req.Value,
		Extend:          req.Extend,
		Status:          req.Status,
		Sort:            req.Sort,
		SysDictionaryID: req.SysDictionaryID,
		ParentID:        req.ParentID,
	}
	return s.uc.CreateDictionaryDetail(ctx, detail)
}

// UpdateDictionaryDetailRequest 更新字典详情请求
type UpdateDictionaryDetailRequest struct {
	ID              uint   `json:"ID"`
	Label           string `json:"label"`
	Value           string `json:"value"`
	Extend          string `json:"extend"`
	Status          *bool  `json:"status"`
	Sort            int    `json:"sort"`
	SysDictionaryID uint   `json:"sysDictionaryID"`
	ParentID        *uint  `json:"parentId"`
}

// UpdateDictionaryDetail 更新字典详情
func (s *DictionaryService) UpdateDictionaryDetail(ctx context.Context, req *UpdateDictionaryDetailRequest) error {
	detail := &system.DictionaryDetail{
		ID:              req.ID,
		Label:           req.Label,
		Value:           req.Value,
		Extend:          req.Extend,
		Status:          req.Status,
		Sort:            req.Sort,
		SysDictionaryID: req.SysDictionaryID,
		ParentID:        req.ParentID,
	}
	return s.uc.UpdateDictionaryDetail(ctx, detail)
}

// DeleteDictionaryDetail 删除字典详情
func (s *DictionaryService) DeleteDictionaryDetail(ctx context.Context, id uint) error {
	return s.uc.DeleteDictionaryDetail(ctx, id)
}

// GetDictionaryDetail 获取字典详情
func (s *DictionaryService) GetDictionaryDetail(ctx context.Context, id uint) (*DictionaryDetailInfo, error) {
	detail, err := s.uc.GetDictionaryDetail(ctx, id)
	if err != nil {
		return nil, err
	}
	return toDictionaryDetailInfo(detail), nil
}

// GetDictionaryDetailListRequest 获取字典详情列表请求
type GetDictionaryDetailListRequest struct {
	Page            int    `json:"page"`
	PageSize        int    `json:"pageSize"`
	Label           string `json:"label"`
	Value           string `json:"value"`
	Status          *bool  `json:"status"`
	SysDictionaryID uint   `json:"sysDictionaryID"`
	ParentID        *uint  `json:"parentId"`
	Level           *int   `json:"level"`
}

// GetDictionaryDetailListResponse 获取字典详情列表响应
type GetDictionaryDetailListResponse struct {
	List     []*DictionaryDetailInfo `json:"list"`
	Total    int64                   `json:"total"`
	Page     int                     `json:"page"`
	PageSize int                     `json:"pageSize"`
}

// GetDictionaryDetailList 获取字典详情列表
func (s *DictionaryService) GetDictionaryDetailList(ctx context.Context, req *GetDictionaryDetailListRequest) (*GetDictionaryDetailListResponse, error) {
	filters := make(map[string]interface{})
	if req.Label != "" {
		filters["label"] = req.Label
	}
	if req.Value != "" {
		filters["value"] = req.Value
	}
	if req.Status != nil {
		filters["status"] = req.Status
	}
	if req.SysDictionaryID != 0 {
		filters["sys_dictionary_id"] = req.SysDictionaryID
	}
	if req.ParentID != nil {
		filters["parent_id"] = req.ParentID
	}
	if req.Level != nil {
		filters["level"] = req.Level
	}

	list, total, err := s.uc.GetDictionaryDetailList(ctx, req.Page, req.PageSize, filters)
	if err != nil {
		return nil, err
	}

	result := make([]*DictionaryDetailInfo, len(list))
	for i, d := range list {
		result[i] = toDictionaryDetailInfo(d)
	}

	return &GetDictionaryDetailListResponse{
		List:     result,
		Total:    total,
		Page:     req.Page,
		PageSize: req.PageSize,
	}, nil
}

// GetDictionaryTreeList 获取字典树形列表
func (s *DictionaryService) GetDictionaryTreeList(ctx context.Context, dictionaryID uint) ([]*DictionaryDetailInfo, error) {
	list, err := s.uc.GetDictionaryTreeList(ctx, dictionaryID)
	if err != nil {
		return nil, err
	}
	return toDictionaryDetailInfoList(list), nil
}

// GetDictionaryDetailsByParentRequest 根据父级获取字典详情请求
type GetDictionaryDetailsByParentRequest struct {
	SysDictionaryID uint  `json:"sysDictionaryID"`
	ParentID        *uint `json:"parentId"`
	IncludeChildren bool  `json:"includeChildren"`
}

// GetDictionaryDetailsByParent 根据父级获取字典详情
func (s *DictionaryService) GetDictionaryDetailsByParent(ctx context.Context, req *GetDictionaryDetailsByParentRequest) ([]*DictionaryDetailInfo, error) {
	list, err := s.uc.GetDictionaryDetailsByParent(ctx, req.SysDictionaryID, req.ParentID, req.IncludeChildren)
	if err != nil {
		return nil, err
	}
	return toDictionaryDetailInfoList(list), nil
}

// GetDictionaryListByType 根据类型获取字典列表
func (s *DictionaryService) GetDictionaryListByType(ctx context.Context, typ string) ([]*DictionaryDetailInfo, error) {
	list, err := s.uc.GetDictionaryListByType(ctx, typ)
	if err != nil {
		return nil, err
	}
	return toDictionaryDetailInfoList(list), nil
}

// GetDictionaryTreeListByType 根据类型获取字典树形列表
func (s *DictionaryService) GetDictionaryTreeListByType(ctx context.Context, typ string) ([]*DictionaryDetailInfo, error) {
	list, err := s.uc.GetDictionaryTreeListByType(ctx, typ)
	if err != nil {
		return nil, err
	}
	return toDictionaryDetailInfoList(list), nil
}

// 转换函数
func toDictionaryInfo(d *system.Dictionary) *DictionaryInfo {
	info := &DictionaryInfo{
		ID:       d.ID,
		Name:     d.Name,
		Type:     d.Type,
		Status:   d.Status,
		Desc:     d.Desc,
		ParentID: d.ParentID,
	}
	if len(d.Children) > 0 {
		info.Children = make([]*DictionaryInfo, len(d.Children))
		for i, c := range d.Children {
			info.Children[i] = toDictionaryInfo(c)
		}
	}
	return info
}

func toDictionaryDetailInfo(d *system.DictionaryDetail) *DictionaryDetailInfo {
	info := &DictionaryDetailInfo{
		ID:              d.ID,
		Label:           d.Label,
		Value:           d.Value,
		Extend:          d.Extend,
		Status:          d.Status,
		Sort:            d.Sort,
		SysDictionaryID: d.SysDictionaryID,
		ParentID:        d.ParentID,
		Level:           d.Level,
		Path:            d.Path,
		Disabled:        d.Disabled,
	}
	if len(d.Children) > 0 {
		info.Children = make([]*DictionaryDetailInfo, len(d.Children))
		for i, c := range d.Children {
			info.Children[i] = toDictionaryDetailInfo(c)
		}
	}
	return info
}

func toDictionaryDetailInfoList(list []*system.DictionaryDetail) []*DictionaryDetailInfo {
	result := make([]*DictionaryDetailInfo, len(list))
	for i, d := range list {
		result[i] = toDictionaryDetailInfo(d)
	}
	return result
}

// RegisterRoutes 注册路由
func (s *DictionaryService) RegisterRoutes(rg *RouterGroup) {
	// 字典接口 - 写操作（带操作记录）
	rg.PrivateWithRecord.POST("/sysDictionary/createSysDictionary", s.handleCreateDictionary)
	rg.PrivateWithRecord.DELETE("/sysDictionary/deleteSysDictionary", s.handleDeleteDictionary)
	rg.PrivateWithRecord.PUT("/sysDictionary/updateSysDictionary", s.handleUpdateDictionary)
	rg.PrivateWithRecord.POST("/sysDictionary/importSysDictionary", s.handleImportDictionary)
	rg.PrivateWithRecord.GET("/sysDictionary/exportSysDictionary", s.handleExportDictionary)

	// 字典接口 - 读操作（不记录）
	rg.Private.GET("/sysDictionary/findSysDictionary", s.handleGetDictionary)
	rg.Private.GET("/sysDictionary/getSysDictionaryList", s.handleGetDictionaryList)

	// 字典详情接口 - 写操作（带操作记录）
	rg.PrivateWithRecord.POST("/sysDictionaryDetail/createSysDictionaryDetail", s.handleCreateDictionaryDetail)
	rg.PrivateWithRecord.DELETE("/sysDictionaryDetail/deleteSysDictionaryDetail", s.handleDeleteDictionaryDetail)
	rg.PrivateWithRecord.PUT("/sysDictionaryDetail/updateSysDictionaryDetail", s.handleUpdateDictionaryDetail)

	// 字典详情接口 - 读操作（不记录）
	rg.Private.GET("/sysDictionaryDetail/findSysDictionaryDetail", s.handleGetDictionaryDetail)
	rg.Private.GET("/sysDictionaryDetail/getSysDictionaryDetailList", s.handleGetDictionaryDetailList)
	rg.Private.GET("/sysDictionaryDetail/getDictionaryTreeList", s.handleGetDictionaryTreeList)
	rg.Private.GET("/sysDictionaryDetail/getDictionaryTreeListByType", s.handleGetDictionaryTreeListByType)
	rg.Private.GET("/sysDictionaryDetail/getDictionaryDetailsByParent", s.handleGetDictionaryDetailsByParent)
	rg.Private.GET("/sysDictionaryDetail/getDictionaryPath", s.handleGetDictionaryPath)
}

// HTTP Handlers - Dictionary
func (s *DictionaryService) handleCreateDictionary(ctx http.Context) error {
	var req CreateDictionaryRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	if err := s.CreateDictionary(ctx, &req); err != nil {
		return errors.BadRequest("CREATE_FAILED", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "创建成功"})
}

func (s *DictionaryService) handleDeleteDictionary(ctx http.Context) error {
	var req struct {
		ID uint `json:"ID"`
	}
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	if err := s.DeleteDictionary(ctx, req.ID); err != nil {
		return errors.BadRequest("DELETE_FAILED", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "删除成功"})
}

func (s *DictionaryService) handleUpdateDictionary(ctx http.Context) error {
	var req UpdateDictionaryRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	if err := s.UpdateDictionary(ctx, &req); err != nil {
		return errors.BadRequest("UPDATE_FAILED", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "更新成功"})
}

func (s *DictionaryService) handleGetDictionary(ctx http.Context) error {
	var req GetDictionaryRequest
	if err := ctx.BindQuery(&req); err != nil {
		return err
	}
	resp, err := s.GetDictionary(ctx, &req)
	if err != nil {
		return errors.NotFound("NOT_FOUND", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": map[string]any{"reSysDictionary": resp}})
}

func (s *DictionaryService) handleGetDictionaryList(ctx http.Context) error {
	var req GetDictionaryListRequest
	if err := ctx.BindQuery(&req); err != nil {
		return err
	}
	resp, err := s.GetDictionaryList(ctx, &req)
	if err != nil {
		return errors.InternalServer("LIST_ERROR", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": map[string]any{"list": resp}})
}

func (s *DictionaryService) handleExportDictionary(ctx http.Context) error {
	idStr := ctx.Query().Get("id")
	id, _ := parseUint(idStr)
	resp, err := s.ExportDictionary(ctx, id)
	if err != nil {
		return errors.InternalServer("EXPORT_ERROR", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "导出成功", "data": resp})
}

func (s *DictionaryService) handleImportDictionary(ctx http.Context) error {
	var req ImportDictionaryRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	if err := s.ImportDictionary(ctx, &req); err != nil {
		return errors.BadRequest("IMPORT_FAILED", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "导入成功"})
}

// HTTP Handlers - DictionaryDetail
func (s *DictionaryService) handleCreateDictionaryDetail(ctx http.Context) error {
	var req CreateDictionaryDetailRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	if err := s.CreateDictionaryDetail(ctx, &req); err != nil {
		return errors.BadRequest("CREATE_FAILED", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "创建成功"})
}

func (s *DictionaryService) handleDeleteDictionaryDetail(ctx http.Context) error {
	var req struct {
		ID uint `json:"ID"`
	}
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	if err := s.DeleteDictionaryDetail(ctx, req.ID); err != nil {
		return errors.BadRequest("DELETE_FAILED", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "删除成功"})
}

func (s *DictionaryService) handleUpdateDictionaryDetail(ctx http.Context) error {
	var req UpdateDictionaryDetailRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	if err := s.UpdateDictionaryDetail(ctx, &req); err != nil {
		return errors.BadRequest("UPDATE_FAILED", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "更新成功"})
}

func (s *DictionaryService) handleGetDictionaryDetail(ctx http.Context) error {
	idStr := ctx.Query().Get("ID")
	id, _ := parseUint(idStr)
	resp, err := s.GetDictionaryDetail(ctx, id)
	if err != nil {
		return errors.NotFound("NOT_FOUND", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": map[string]any{"reSysDictionaryDetail": resp}})
}

func (s *DictionaryService) handleGetDictionaryDetailList(ctx http.Context) error {
	var req GetDictionaryDetailListRequest
	if err := ctx.BindQuery(&req); err != nil {
		return err
	}
	resp, err := s.GetDictionaryDetailList(ctx, &req)
	if err != nil {
		return errors.InternalServer("LIST_ERROR", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": resp})
}

func (s *DictionaryService) handleGetDictionaryTreeList(ctx http.Context) error {
	idStr := ctx.Query().Get("sysDictionaryID")
	id, _ := parseUint(idStr)
	resp, err := s.GetDictionaryTreeList(ctx, id)
	if err != nil {
		return errors.InternalServer("LIST_ERROR", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": map[string]any{"list": resp}})
}

func (s *DictionaryService) handleGetDictionaryDetailsByParent(ctx http.Context) error {
	var req GetDictionaryDetailsByParentRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	resp, err := s.GetDictionaryDetailsByParent(ctx, &req)
	if err != nil {
		return errors.InternalServer("LIST_ERROR", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": map[string]any{"list": resp}})
}

func (s *DictionaryService) handleGetDictionaryListByType(ctx http.Context) error {
	typ := ctx.Query().Get("type")
	resp, err := s.GetDictionaryListByType(ctx, typ)
	if err != nil {
		return errors.InternalServer("LIST_ERROR", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": map[string]any{"list": resp}})
}

func (s *DictionaryService) handleGetDictionaryTreeListByType(ctx http.Context) error {
	typ := ctx.Query().Get("type")
	resp, err := s.GetDictionaryTreeListByType(ctx, typ)
	if err != nil {
		return errors.InternalServer("LIST_ERROR", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": map[string]any{"list": resp}})
}

func (s *DictionaryService) handleGetDictionaryPath(ctx http.Context) error {
	idStr := ctx.Query().Get("id")
	id, _ := parseUint(idStr)
	resp, err := s.uc.GetDictionaryPath(ctx, id)
	if err != nil {
		return errors.InternalServer("PATH_ERROR", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": map[string]any{"path": toDictionaryDetailInfoList(resp)}})
}

// parseUint 解析uint
func parseUint(s string) (uint, error) {
	if s == "" {
		return 0, nil
	}
	var id uint
	_, err := fmt.Sscanf(s, "%d", &id)
	return id, err
}
