package user

import (
	"backend/pkg/member/domain/member"
	"backend/pkg/member/domain/usecase"
	"backend/pkg/permission/domain/token"
	"context"
	"time"

	"google.golang.org/protobuf/proto"

	"backend/internal/svc"
	"backend/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetUserInfoLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// NewGetUserInfoLogic 取得當前登入的會員資訊(自己)
func NewGetUserInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserInfoLogic {
	return &GetUserInfoLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *GetUserInfoLogic) GetUserInfo(req *types.Authorization) (*types.MyInfo, error) {
	uid := token.UID(l.ctx)
	info, err := l.svcCtx.AccountUC.GetUserInfo(l.ctx, usecase.GetUserInfoRequest{
		UID: uid,
	})
	if err != nil {
		return nil, err
	}

	byUID, err := l.svcCtx.AccountUC.FindLoginIDByUID(l.ctx, uid)
	if err != nil {
		return nil, err
	}

	accountInfo, err := l.svcCtx.AccountUC.GetUserAccountInfo(l.ctx, usecase.GetUIDByAccountRequest{
		Account: byUID.LoginID,
	})
	if err != nil {
		return nil, err
	}

	userRole, err := l.svcCtx.UserRoleUC.Get(l.ctx, uid)
	if err != nil {
		return nil, err
	}
	role := userRole.RoleUID
	res := &types.MyInfo{
		Platform:          accountInfo.Data.Platform.ToString(),
		UID:               info.UID,
		UpdateAt:          time.Unix(0, info.CreateTime).UTC().Format(time.RFC3339),
		CreateAt:          time.Unix(0, info.UpdateTime).UTC().Format(time.RFC3339),
		Role:              role,
		UserStatus:        info.UserStatus.CodeToString(),
		PreferredLanguage: info.PreferredLanguage,
		Currency:          info.Currency,
		AlarmCategory:     info.AlarmCategory.CodeToString(),
	}
	if info.Address != nil {
		res.Address = info.Address
	}
	if info.AvatarURL != nil {
		res.AvatarURL = info.AvatarURL
	}
	if info.FullName != nil {
		res.FullName = info.FullName
	}

	if info.Birthdate != nil {
		b := ToDate(info.Birthdate)
		res.Birthdate = b
	}

	if info.Address != nil {
		res.Address = info.Address
	}

	if info.Nickname != nil {
		res.Nickname = info.Nickname
	}

	if info.Email != nil {
		res.Email = info.Email
		res.IsEmailVerified = proto.Bool(true)
	}

	if info.PhoneNumber != nil {
		res.PhoneNumber = info.PhoneNumber
		res.IsPhoneVerified = proto.Bool(true)
	}
	if info.GenderCode != nil {
		gc := member.GetGenderByCode(*info.GenderCode)
		res.GenderCode = &gc
	}

	return res, nil
}

func ToDate(n *int64) *string {
	result := ""
	if n != nil {
		result = time.Unix(*n, 0).UTC().Format(time.DateOnly)
	}

	return &result
}
