# frozen_string_literal: true

class CrewMembership < ApplicationRecord
  belongs_to :crew
  belongs_to :user
  has_many :gw_individual_scores, dependent: :nullify

  enum :role, { member: 0, vice_captain: 1, captain: 2 }

  before_validation :set_joined_at, on: :create

  validates :user_id, uniqueness: { scope: :crew_id }
  validate :one_active_crew_per_user, on: :create
  validate :captain_limit
  validate :vice_captain_limit

  scope :active, -> { where(retired: false) }
  scope :retired, -> { where(retired: true) }

  # Members who were active during a date range (either still active, or retired after the end date)
  # Uses joined_at (editable) instead of created_at (system timestamp) for historical accuracy
  scope :active_during, ->(start_date, end_date) {
    where('retired = false OR retired_at >= ?', start_date)
      .where('joined_at <= ?', end_date)
  }

  def retire!
    update!(retired: true, retired_at: Time.current, role: :member)
  end

  def officer?
    captain? || vice_captain?
  end

  def blueprint
    CrewMembershipBlueprint
  end

  private

  def set_joined_at
    self.joined_at ||= Time.current
  end

  def one_active_crew_per_user
    return if retired

    if CrewMembership.where(user_id: user_id, retired: false).where.not(id: id).exists?
      errors.add(:user, 'can only be in one active crew')
    end
  end

  def captain_limit
    return unless captain? && !retired

    existing = crew.crew_memberships.where(role: :captain, retired: false).where.not(id: id)
    errors.add(:role, 'crew can only have one captain') if existing.exists?
  end

  def vice_captain_limit
    return unless vice_captain? && !retired

    existing = crew.crew_memberships.where(role: :vice_captain, retired: false).where.not(id: id)
    errors.add(:role, 'crew can only have up to 3 vice captains') if existing.count >= 3
  end
end
