module JamRuby
  class BandInvitation < ActiveRecord::Base

    self.table_name = "band_invitations"

    self.primary_key = 'id'

    BAND_INVITATION_FAN_RECIPIENT_ERROR = "A Band invitation can only be sent to a Musician."

    validates_uniqueness_of :user_id, scope: :band_id

    belongs_to :receiver, :inverse_of => :received_band_invitations, :foreign_key => "user_id", :class_name => "JamRuby::User"
    belongs_to :sender, :inverse_of => :sent_band_invitations, :foreign_key => "creator_id", :class_name => "JamRuby::User"
    belongs_to :band, :inverse_of => :invitations, :foreign_key => "band_id", :class_name => "JamRuby::Band"

    def self.save(id, band_id, user_id, creator_id, accepted, resend=false)

      band_invitation = BandInvitation.new()

      ActiveRecord::Base.transaction do
        # ensure certain fields are only updated on creation
        if id.nil?
          # ensure recipient is a Musician
          user = User.find(user_id)
          unless user.musician?
            raise JamRuby::JamArgumentError.new(BAND_INVITATION_FAN_RECIPIENT_ERROR, :receiver)
          end

          band_invitation.band_id = band_id
          band_invitation.user_id = user_id
          band_invitation.creator_id = creator_id
          band_invitation.save

          Notification.send_band_invitation(
            band_invitation.band,
            band_invitation,
            band_invitation.sender,
            band_invitation.receiver
          )

        # only the accepted flag can be updated after initial creation
        else
          band_invitation = BandInvitation.find(id)
          if resend
            Notification.send_band_invitation(
                                              band_invitation.band,
                                              band_invitation,
                                              band_invitation.sender,
                                              band_invitation.receiver
                                              )
          else
            band_invitation.accepted = accepted
            band_invitation.save
          end
        end

        # accept logic:
        # (1) auto-friend each band member
        # (2) add the musician to the band
        # (3) send BAND_INVITATION_ACCEPTED notification
        if accepted
          band_musicians = BandMusician.where(:band_id => band_invitation.band.id)
          unless band_musicians.blank?
            # auto-friend and notify each band member
            band_musicians.each do |bm|
              Friendship.save(band_invitation.receiver.id, bm.user_id)
              Notification.send_band_invitation_accepted(
                band_invitation.band,
                band_invitation,
                band_invitation.receiver,
                bm.user
              )
            end
          end

          # accepting an invitation adds the musician to the band
          BandMusician.create(:band_id => band_invitation.band.id, :user_id => band_invitation.receiver.id, :admin => false)
        end
      end
      band_invitation
    end
  end
end
