# 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
