package svc

import (
	"context"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/ent"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/types/core"
	"git.noahlan.cn/noahlan/ntool/ntime"
	"github.com/jinzhu/copier"
)

type Convert struct {
	svcCtx *ServiceContext
}

func NewConvert(svcCtx *ServiceContext) *Convert {
	return &Convert{
		svcCtx: svcCtx,
	}
}

func (c *Convert) ConvertRoleRpc(_ context.Context, v *ent.Role) *core.RoleInfo {
	if v == nil {
		return nil
	}
	var tmp core.RoleInfo
	_ = copier.Copy(&tmp, v)
	tmp.CreatedAt = ntime.Format(v.CreatedAt)
	tmp.UpdatedAt = ntime.Format(v.UpdatedAt)
	tmp.Status = v.Status.String()

	return &tmp
}

func (c *Convert) ConvertUserRpc(ctx context.Context, v *ent.User) *core.UserInfo {
	if v == nil {
		return nil
	}
	var tmp core.UserInfo
	_ = copier.Copy(&tmp, v)
	tmp.Status = v.Status.String()
	tmp.CreatedAt = ntime.Format(v.CreatedAt)
	tmp.UpdatedAt = ntime.Format(v.UpdatedAt)

	// Metadata
	if len(v.Edges.Metas) > 0 {
		// 导出meta数据
		metaMap := make(map[string]string)
		for _, item := range v.Edges.Metas {
			metaMap[item.Key] = item.Value
		}
		tmp.Metas = metaMap
	}

	// Relationship
	if len(v.Edges.Roles) > 0 {
		tmp.Roles = make([]*core.RoleInfo, len(v.Edges.Roles))
		for i, item := range v.Edges.Roles {
			tmp.Roles[i] = c.ConvertRoleRpc(ctx, item)
		}
	}
	if v.Edges.LoginRecord != nil {
		tmp.LoginRecord = c.ConvertLoginRecordRpc(ctx, v.Edges.LoginRecord)
	}
	if len(v.Edges.Departments) > 0 {
		tmp.Departments = make([]*core.DepartmentInfo, len(v.Edges.Departments))
		for i, item := range v.Edges.Departments {
			tmp.Departments[i] = c.ConvertDepartmentRpc(ctx, item)
		}
	}
	if len(v.Edges.Token) > 0 {
		tmp.Tokens = make([]*core.TokenInfo, len(v.Edges.Token))
		for i, item := range v.Edges.Token {
			tmp.Tokens[i] = c.ConvertTokenRpc(ctx, item)
		}
	}
	if len(v.Edges.Socials) > 0 {
		tmp.Socials = make([]*core.UserSocialInfo, len(v.Edges.Socials))
		for i, item := range v.Edges.Socials {
			tmp.Socials[i] = c.ConvertUserSocialRpc(ctx, item)
		}
	}

	return &tmp
}

func (c *Convert) ConvertTokenRpc(ctx context.Context, v *ent.Token) *core.TokenInfo {
	if v == nil {
		return nil
	}
	var tmp core.TokenInfo
	_ = copier.Copy(&tmp, v)
	tmp.CreatedAt = ntime.Format(v.CreatedAt)
	tmp.UpdatedAt = ntime.Format(v.UpdatedAt)
	tmp.UserId = v.UserID

	if v.Edges.User != nil {
		tmp.User = c.ConvertUserRpc(ctx, v.Edges.User)
	}
	return &tmp
}

func (c *Convert) ConvertUserSocialRpc(ctx context.Context, v *ent.UserSocial) *core.UserSocialInfo {
	if v == nil {
		return nil
	}
	var tmp core.UserSocialInfo
	_ = copier.Copy(&tmp, v)
	tmp.CreatedAt = ntime.Format(v.CreatedAt)
	tmp.UpdatedAt = ntime.Format(v.UpdatedAt)
	tmp.UserId = v.UserID
	tmp.Uid = v.UID
	tmp.OpenId = v.OpenID
	tmp.UnionId = v.UnionID

	if v.Edges.User != nil {
		tmp.User = c.ConvertUserRpc(ctx, v.Edges.User)
	}

	return &tmp
}

func (c *Convert) ConvertLoginRecordRpc(_ context.Context, v *ent.LoginRecord) *core.LoginRecordInfo {
	if v == nil {
		return nil
	}
	var tmp core.LoginRecordInfo
	_ = copier.Copy(&tmp, v)
	tmp.CreatedAt = ntime.Format(v.CreatedAt)
	tmp.UpdatedAt = ntime.Format(v.UpdatedAt)

	tmp.UserId = v.UserID
	tmp.LastLoginUa = v.LastLoginUA
	return &tmp
}

func (c *Convert) ConvertDepartmentRpc(ctx context.Context, v *ent.Department) *core.DepartmentInfo {
	if v == nil {
		return nil
	}
	var tmp core.DepartmentInfo
	_ = copier.Copy(&tmp, v)
	tmp.CreatedAt = ntime.Format(v.CreatedAt)
	tmp.UpdatedAt = ntime.Format(v.UpdatedAt)

	tmp.LeaderId = v.LeaderID
	tmp.ParentId = v.ParentID
	// relationship
	if v.Edges.Parent != nil {
		tmp.Parent = c.ConvertDepartmentRpc(ctx, v.Edges.Parent)
	}
	if len(v.Edges.Children) > 0 {
		tmp.Children = make([]*core.DepartmentInfo, len(v.Edges.Children))
		for i, item := range v.Edges.Children {
			tmp.Children[i] = c.ConvertDepartmentRpc(ctx, item)
		}
	}
	if len(v.Edges.Users) > 0 {
		tmp.Users = make([]*core.UserInfo, len(v.Edges.Users))
		for i, item := range v.Edges.Users {
			tmp.Users[i] = c.ConvertUserRpc(ctx, item)
		}
	}
	if v.Edges.Leader != nil {
		tmp.Leader = c.ConvertUserRpc(ctx, v.Edges.Leader)
	}

	return &tmp
}

func (c *Convert) ConvertOAuthProviderRpc(_ context.Context, v *ent.OauthProvider) *core.OauthProviderInfo {
	if v == nil {
		return nil
	}
	var tmp core.OauthProviderInfo
	_ = copier.Copy(&tmp, v)
	tmp.CreatedAt = ntime.Format(v.CreatedAt)
	tmp.UpdatedAt = ntime.Format(v.UpdatedAt)
	tmp.ClientId = v.ClientID
	tmp.RedirectUrl = v.RedirectURL
	tmp.AuthUrl = v.AuthURL
	tmp.TokenUrl = v.TokenURL
	tmp.InfoUrl = v.InfoURL

	return &tmp
}

func (c *Convert) ConvertDistrictRpc(_ context.Context, v *ent.District) *core.DistrictInfo {
	if v == nil {
		return nil
	}
	var tmp core.DistrictInfo
	_ = copier.Copy(&tmp, v)
	tmp.CreatedAt = ntime.Format(v.CreatedAt)
	tmp.UpdatedAt = ntime.Format(v.UpdatedAt)

	return &tmp
}

func (c *Convert) ConvertDictionaryRpc(ctx context.Context, v *ent.Dictionary) *core.DictionaryInfo {
	if v == nil {
		return nil
	}
	var tmp core.DictionaryInfo
	_ = copier.Copy(&tmp, v)
	tmp.CreatedAt = ntime.Format(v.CreatedAt)
	tmp.UpdatedAt = ntime.Format(v.UpdatedAt)

	if len(v.Edges.Details) > 0 {
		tmp.Details = make([]*core.DictionaryDetailInfo, len(v.Edges.Details))
		for i, item := range v.Edges.Details {
			tmp.Details[i] = c.ConvertDictionaryDetailRpc(ctx, item)
		}
	}
	return &tmp
}

func (c *Convert) ConvertDictionaryDetailRpc(_ context.Context, v *ent.DictionaryDetail) *core.DictionaryDetailInfo {
	if v == nil {
		return nil
	}
	var tmp core.DictionaryDetailInfo
	_ = copier.Copy(&tmp, v)
	tmp.DictionaryId = v.DictionaryID

	return &tmp
}
