# frozen_string_literal: true module UserFamily extend ActiveSupport::Concern included do has_one :family_membership, dependent: :destroy, class_name: 'Family::Membership' has_one :family, through: :family_membership has_one :created_family, class_name: 'Family', foreign_key: 'creator_id', inverse_of: :creator, dependent: :destroy has_many :sent_family_invitations, class_name: 'Family::Invitation', foreign_key: 'invited_by_id', inverse_of: :invited_by, dependent: :destroy before_destroy :check_family_ownership end def in_family? family_membership.present? end def family_owner? family_membership&.owner? == true end def can_delete_account? return true unless family_owner? return true unless family family.members.count <= 1 end def family_sharing_enabled? return false unless in_family? sharing_settings = settings.dig('family', 'location_sharing') return false unless sharing_settings.is_a?(Hash) return false unless sharing_settings['enabled'] == true expires_at = sharing_settings['expires_at'] expires_at.blank? || Time.parse(expires_at).future? end def update_family_location_sharing!(enabled, duration: nil) return false unless in_family? current_settings = settings || {} current_settings['family'] ||= {} if enabled sharing_config = { 'enabled' => true } if duration.present? expiration_time = case duration when '1h' then 1.hour.from_now when '6h' then 6.hours.from_now when '12h' then 12.hours.from_now when '24h' then 24.hours.from_now when 'permanent' then nil else duration.to_i.hours.from_now if duration.to_i > 0 end sharing_config['expires_at'] = expiration_time.iso8601 if expiration_time sharing_config['duration'] = duration end current_settings['family']['location_sharing'] = sharing_config else current_settings['family']['location_sharing'] = { 'enabled' => false } end update!(settings: current_settings) end def family_sharing_expires_at sharing_settings = settings.dig('family', 'location_sharing') return nil unless sharing_settings.is_a?(Hash) expires_at = sharing_settings['expires_at'] Time.parse(expires_at) if expires_at.present? rescue ArgumentError nil end def family_sharing_duration settings.dig('family', 'location_sharing', 'duration') || 'permanent' end def latest_location_for_family return nil unless family_sharing_enabled? latest_point = points.select(:lonlat, :timestamp) .order(timestamp: :desc) .limit(1) .first return nil unless latest_point { user_id: id, email: email, latitude: latest_point.lat, longitude: latest_point.lon, timestamp: latest_point.timestamp, updated_at: Time.zone.at(latest_point.timestamp) } end private def check_family_ownership return if can_delete_account? errors.add(:base, 'Cannot delete account while being a family owner with other members') raise ActiveRecord::DeleteRestrictionError, 'Cannot delete user with family members' end end