package admin

import (
	"context"
	"strconv"

	"apps/backend/internal/module/member/domain"
	memberUC "apps/backend/internal/module/member/usecase"
	"apps/backend/internal/svc"
	"apps/backend/internal/types"

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

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

func NewAdminResetPasswordLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminResetPasswordLogic {
	return &AdminResetPasswordLogic{Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx}
}

func (l *AdminResetPasswordLogic) AdminResetPassword(req *types.AdminResetPasswordReq) (resp *types.AdminCreateMemberData, err error) {
	uid, err := strconv.ParseInt(req.Uid, 10, 64)
	if err != nil {
		return nil, err
	}
	tmp := req.NewPassword
	if tmp == "" {
		tmp = req.Password
	}
	if tmp == "" {
		tmp = memberUC.GenerateTempPassword()
	} else if err := memberUC.ValidatePasswordPolicy(tmp); err != nil {
		return nil, err
	}
	m, err := l.svcCtx.Members.FindByUID(l.ctx, uid)
	if err != nil {
		return nil, err
	}
	loginID := m.Email
	if loginID == "" {
		loginID = m.Phone
	}
	if loginID == "" {
		return nil, domain.ErrNotFound
	}
	// prefer identity path; fall back to member hash + create identity
	if err := l.svcCtx.Auth.UpdateUserToken(l.ctx, loginID, domain.PlatformPassword, tmp); err != nil {
		hash, herr := memberUC.HashPassword(tmp, 10)
		if herr != nil {
			return nil, herr
		}
		m.PasswordHash = hash
		m.UpdatedAt = domain.NowNano()
		if err := l.svcCtx.Members.UpdateMember(l.ctx, m); err != nil {
			return nil, err
		}
		_ = l.svcCtx.Members.CreateIdentity(l.ctx, &domain.Identity{
			UID: uid, LoginID: loginID, Platform: domain.PlatformPassword,
			AccountType: domain.AccountTypeEmail, PasswordHash: hash,
			CreatedAt: domain.NowNano(), UpdatedAt: domain.NowNano(),
		})
	} else {
		m, _ = l.svcCtx.Members.FindByUID(l.ctx, uid)
	}
	return &types.AdminCreateMemberData{User: *types.MemberFromModel(m), TemporaryPassword: tmp}, nil
}
