package types

import (
	"strings"

	memberDomain "apps/backend/internal/module/member/domain"
)

// MemberFromModel maps domain member → goctl MemberPublic (no identities).
func MemberFromModel(m *memberDomain.Member) *MemberPublic {
	return MemberFromModelWithIdentities(m, nil)
}

// MemberFromModelWithIdentities includes bound login channels.
func MemberFromModelWithIdentities(m *memberDomain.Member, ids []*memberDomain.Identity) *MemberPublic {
	if m == nil {
		return nil
	}
	out := &MemberPublic{
		TenantId: m.TenantID, Uid: m.UID, Email: m.Email, Phone: m.Phone,
		DisplayName: m.DisplayName, Nickname: m.Nickname, FullName: m.FullName,
		Roles: m.Roles, Status: m.Status, EmailVerified: m.EmailVerified,
		PhoneVerified: m.PhoneVerified, InviteCode: m.InviteCode,
		Bio: m.Bio, Timezone: m.Timezone, AvatarUrl: m.AvatarURL,
		NotifyEmail: m.NotifyEmail, GenderCode: int(m.GenderCode), Birthdate: m.Birthdate,
		National: m.National, Address: m.Address, PostCode: m.PostCode,
		PreferredLanguage: m.PreferredLanguage, Currency: m.Currency,
		OnboardingStatus: m.OnboardingStatus, OnboardingDoneAt: m.OnboardingDoneAt,
		JoinedAt: m.CreatedAt, CreatedAt: m.CreatedAt, UpdatedAt: m.UpdatedAt,
	}
	if m.EmailVerifiedAt != nil {
		out.EmailVerifiedAt = *m.EmailVerifiedAt
	}
	if m.PhoneVerifiedAt != nil {
		out.PhoneVerifiedAt = *m.PhoneVerifiedAt
	}
	if m.ParentUID != nil {
		out.ParentUid = *m.ParentUID
	}
	if len(ids) > 0 {
		out.Identities = make([]IdentityPublic, 0, len(ids))
		for _, id := range ids {
			out.Identities = append(out.Identities, IdentityFromModel(id))
		}
	}
	return out
}

func IdentityFromModel(id *memberDomain.Identity) IdentityPublic {
	if id == nil {
		return IdentityPublic{}
	}
	return IdentityPublic{
		LoginId: id.LoginID, Platform: id.Platform,
		AccountType: id.AccountType, CreatedAt: id.CreatedAt,
	}
}

func TokenPairFromAuth(access, refresh, tokenType string, expiresIn int64) TokenPair {
	return TokenPair{AccessToken: access, RefreshToken: refresh, TokenType: tokenType, ExpiresIn: expiresIn}
}

// PatchFromAuthProfile builds domain patch from API request.
func PatchFromAuthProfile(req *AuthProfilePatchReq) *memberDomain.UpdateUserInfoPatch {
	if req == nil {
		return nil
	}
	p := &memberDomain.UpdateUserInfoPatch{}
	if req.DisplayName != "" {
		p.DisplayName = &req.DisplayName
	}
	if req.Nickname != "" {
		p.Nickname = &req.Nickname
	}
	if req.FullName != "" {
		p.FullName = &req.FullName
	}
	if req.Email != "" {
		p.Email = &req.Email
	}
	if req.Phone != "" {
		p.Phone = &req.Phone
	}
	if req.Bio != "" {
		p.Bio = &req.Bio
	}
	if req.Timezone != "" {
		p.Timezone = &req.Timezone
	}
	if req.NotifyEmail != nil {
		p.NotifyEmail = req.NotifyEmail
	}
	// nil = omit（不改）；非 nil 含 "" = 明確寫入／清除
	if req.AvatarUrl != nil {
		u := strings.TrimSpace(*req.AvatarUrl)
		p.AvatarURL = &u
	}
	if req.GenderCode != nil {
		g := int8(*req.GenderCode)
		p.GenderCode = &g
	}
	if req.Birthdate != nil {
		p.Birthdate = req.Birthdate
	}
	if req.National != "" {
		p.National = &req.National
	}
	if req.Address != "" {
		p.Address = &req.Address
	}
	if req.PostCode != "" {
		p.PostCode = &req.PostCode
	}
	if req.PreferredLanguage != "" {
		p.PreferredLanguage = &req.PreferredLanguage
	}
	if req.Currency != "" {
		p.Currency = &req.Currency
	}
	if req.OnboardingStatus != "" {
		p.OnboardingStatus = &req.OnboardingStatus
	}
	if req.CurrentPassword != "" {
		p.CurrentPassword = &req.CurrentPassword
	}
	if req.NewPassword != "" {
		p.NewPassword = &req.NewPassword
	}
	return p
}
