class Lato::User

def accept_invitation(params)

def accept_invitation(params)
  invitation = Lato::Invitation.find_by(id: params[:id], accepted_code: params[:accepted_code])
  if !invitation || invitation.accepted? || invitation.email != email
    errors.add(:base, :invitation_invalid)
    return
  end
  ActiveRecord::Base.transaction do
    raise ActiveRecord::Rollback unless save && invitation.update(
      accepted_at: Time.now,
      lato_user_id: id
    )
    true
  end
end

def add_web3_connection(params)

def add_web3_connection(params)
  depends_on('eth')
  signature_pubkey = Eth::Signature.personal_recover(params[:web3_nonce], params[:web3_signed_nonce])
  signature_address = Eth::Util.public_key_to_address signature_pubkey
  unless signature_address.to_s.downcase == params[:web3_address].downcase
    errors.add(:base, :web3_address_invalid)
    return
  end
  update(web3_address: params[:web3_address])
rescue StandardError => e
  errors.add(:base, :web3_connection_error)
  false
end

def authenticator(params)

def authenticator(params)
  return false unless authenticator_enabled?
  totp = ROTP::TOTP.new(authenticator_secret)
  result = totp.verify(params[:authenticator_code])
  unless result
    errors.add(:base, :authenticator_code_invalid)
    return
  end
  true
end

def authenticator_enabled?

def authenticator_enabled?
  !authenticator_secret.blank?
end

def authenticator_qr_code_base64(size = 200)

def authenticator_qr_code_base64(size = 200)
  "data:image/png;base64,#{Base64.strict_encode64(RQRCode::QRCode.new(ROTP::TOTP.new(authenticator_secret, :issuer => Lato.config.application_title).provisioning_uri(email).to_s).as_png(size: size, border_modules: 0).to_s)}"
end

def c_email_verification_code(value = nil)

def c_email_verification_code(value = nil)
  cache_key = "Lato::User/c_email_verification_code/#{id}"
  return Rails.cache.read(cache_key) if value.nil?
  Rails.cache.write(cache_key, value, expires_in: 30.minutes)
  value
end

def c_email_verification_semaphore(value = nil)

def c_email_verification_semaphore(value = nil)
  cache_key = "Lato::User/c_email_verification_semaphore/#{id}"
  return Rails.cache.read(cache_key) if value.nil?
  Rails.cache.write(cache_key, value, expires_in: 2.minutes)
  value
end

def c_password_update_code(value = nil)

def c_password_update_code(value = nil)
  cache_key = "Lato::User/c_password_update_code/#{id}"
  return Rails.cache.read(cache_key) if value.nil?
  Rails.cache.write(cache_key, value, expires_in: 30.minutes)
  value
end

def destroy_with_confirmation(params)

def destroy_with_confirmation(params)
  unless params[:email_confirmation] == email
    errors.add(:email, :not_correct)
    return
  end
  destroy
end

def email_protected

def email_protected
  return email unless email.include?('@')
  local_part, domain = email.split('@', 2)
  
  # Keep first 2 characters of local part
  chars_to_keep = [local_part.length, 2].min
  protected_local = local_part[0, chars_to_keep] + '*' * [local_part.length - chars_to_keep, 0].max
  
  # Keep domain as is or partially protect it
  chars_to_keep = [domain.length, 2].min
  protected_domain = domain[0, chars_to_keep] + '*' * [domain.length - chars_to_keep, 0].max
  
  "#{protected_local}@#{protected_domain}"
end

def full_name

def full_name
  "#{last_name} #{first_name}"
end

def generate_authenticator_secret

def generate_authenticator_secret
  update(authenticator_secret: ROTP::Base32.random)
end

def gravatar_image_url(size = 200)

def gravatar_image_url(size = 200)
  @gravatar_image_url ||= "https://www.gravatar.com/avatar/#{Digest::MD5.hexdigest(email)}?s=#{size}"
end

def remove_authenticator_secret

def remove_authenticator_secret
  update(authenticator_secret: nil)
end

def remove_web3_connection

def remove_web3_connection
  update(web3_address: nil)
  true
end

def request_recover_password(params)

def request_recover_password(params)
  user = Lato::User.find_by(email: params[:email])
  unless user
    errors.add(:email, :not_registered)
    return
  end
  code = SecureRandom.hex.upcase
  delivery = Lato::UserMailer.password_update_mail(user.id, code).deliver_now
  unless delivery
    errors.add(:base, :email_sending_error)
    return
  end
  self.id = user.id
  reload
  c_password_update_code(code)
  true
end

def request_verify_email

def request_verify_email
  if c_email_verification_semaphore
    errors.add(:base, :email_verification_limit)
    return
  end
  code = SecureRandom.hex.upcase
  delivery = Lato::UserMailer.email_verification_mail(id, code).deliver_now
  unless delivery
    errors.add(:base, :email_sending_error)
    return
  end
  c_email_verification_code(code)
  c_email_verification_semaphore(true)
  true
end

def signin(params)

def signin(params)
  self.email = params[:email]
  user = Lato::User.find_by(email: params[:email])
  unless user
    errors.add(:email, :not_correct)
    return
  end
  unless user.authenticate(params[:password])
    errors.add(:password, :not_correct)
    return
  end
  self.id = user.id
  reload
  begin
    lato_log_user_signins.create(
      ip_address: params[:ip_address],
      user_agent: params[:user_agent]
    )
  rescue StandardError => e
    Rails.logger.error(e)
  end
  Lato::UserMailer.signin_success_mail(id, params[:ip_address]).deliver_later
  true
end

def signup(params = {})

def signup(params = {})
  return unless save
  begin
    lato_log_user_signups.create(
      ip_address: params[:ip_address],
      user_agent: params[:user_agent]
    )
  rescue StandardError => e
    Rails.logger.error(e)
  end
  true
end

def update_accepted_privacy_policy_version(params)

def update_accepted_privacy_policy_version(params)
  unless params[:confirm]
    errors.add(:base, :privacy_policy_invalid)
    return
  end
  update(accepted_privacy_policy_version: Lato.config.legal_privacy_policy_version)
end

def update_accepted_terms_and_conditions_version(params)

def update_accepted_terms_and_conditions_version(params)
  unless params[:confirm]
    errors.add(:base, :terms_and_conditions_invalid)
    return
  end
  update(accepted_terms_and_conditions_version: Lato.config.legal_terms_and_conditions_version)
end

def update_password(params)

def update_password(params)
  password_update_code = c_password_update_code
  if password_update_code.blank?
    errors.add(:base, :password_update_code_expired)
    return
  end
  unless password_update_code == params[:code]
    errors.add(:base, :password_update_code_invalid)
    return
  end
  c_password_update_code('')
  update(params.permit(:password, :password_confirmation).merge(
    authenticator_secret: nil # Reset authenticator secret when password is updated
  ))
end

def valid_accepted_privacy_policy_version?

def valid_accepted_privacy_policy_version?
  @valid_accepted_privacy_policy_version ||= accepted_privacy_policy_version >= Lato.config.legal_privacy_policy_version
end

def valid_accepted_terms_and_conditions_version?

def valid_accepted_terms_and_conditions_version?
  @valid_accepted_terms_and_conditions_version ||= accepted_terms_and_conditions_version >= Lato.config.legal_terms_and_conditions_version
end

def verify_email(params)

def verify_email(params)
  email_verification_code = c_email_verification_code
  if email_verification_code.blank?
    errors.add(:base, :email_verification_code_expired)
    return
  end
  unless email_verification_code == params[:code]
    errors.add(:base, :email_verification_code_invalid)
    return
  end
  c_email_verification_code('')
  c_email_verification_semaphore(false)
  update_column(:email_verified_at, Time.now)
  true
end

def web3_signin(params)

def web3_signin(params)
  depends_on('eth')
  self.web3_address = params[:web3_address]
  user = Lato::User.find_by(web3_address: params[:web3_address].downcase)
  unless user
    errors.add(:web3_address, :not_correct)
    return
  end
  signature_pubkey = Eth::Signature.personal_recover(params[:web3_nonce], params[:web3_signed_nonce])
  signature_address = Eth::Util.public_key_to_address signature_pubkey
  unless signature_address.to_s.downcase == params[:web3_address].downcase
    errors.add(:web3_signed_nonce, :not_correct)
    return
  end
  self.id = user.id
  reload
  begin
    lato_log_user_signins.create(
      ip_address: params[:ip_address],
      user_agent: params[:user_agent]
    )
  rescue StandardError => e
    Rails.logger.error(e)
  end
  true
rescue StandardError => e
  errors.add(:base, :web3_connection_error)
  false
end