class CollectionCharacter < ApplicationRecord
  belongs_to :user
  belongs_to :character
  belongs_to :awakening, optional: true

  before_save :add_default_awakening

  validates :character_id, uniqueness: { scope: :user_id,
    message: "already exists in your collection" }
  validates :uncap_level, inclusion: { in: 0..5 }
  validates :transcendence_step, inclusion: { in: 0..10 }
  validates :awakening_level, inclusion: { in: 1..10 }

  validate :validate_rings
  validate :validate_awakening_compatibility
  validate :validate_awakening_level
  validate :validate_transcendence_requirements

  scope :by_element, ->(element) { joins(:character).where(characters: { element: element }) }
  scope :by_rarity, ->(rarity) { joins(:character).where(characters: { rarity: rarity }) }
  scope :by_race, ->(races) {
    joins(:character).where('characters.race1 IN (?) OR characters.race2 IN (?)', races, races)
  }
  scope :by_proficiency, ->(proficiencies) {
    joins(:character).where('characters.proficiency1 IN (?) OR characters.proficiency2 IN (?)', proficiencies, proficiencies)
  }
  scope :by_gender, ->(genders) { joins(:character).where(characters: { gender: genders }) }
  scope :transcended, -> { where('transcendence_step > 0') }
  scope :with_awakening, -> { where.not(awakening_id: nil) }

  # Sorting scopes
  scope :sorted_by, ->(sort_key) {
    case sort_key
    when 'name_asc'
      joins(:character).order('characters.name_en ASC NULLS LAST')
    when 'name_desc'
      joins(:character).order('characters.name_en DESC NULLS LAST')
    when 'element_asc'
      joins(:character).order('characters.element ASC')
    when 'element_desc'
      joins(:character).order('characters.element DESC')
    when 'proficiency_asc'
      joins(:character).order('characters.proficiency1 ASC')
    when 'proficiency_desc'
      joins(:character).order('characters.proficiency1 DESC')
    else
      order(created_at: :desc) # Default: newest first
    end
  }

  def blueprint
    Api::V1::CollectionCharacterBlueprint
  end

  private

  def validate_rings
    [ring1, ring2, ring3, ring4, earring].each_with_index do |ring, index|
      next unless ring['modifier'].present? || ring['strength'].present?

      if ring['modifier'].blank? || ring['strength'].blank?
        errors.add(:base, "Ring #{index + 1} must have both modifier and strength")
      end
    end
  end

  def validate_awakening_compatibility
    return unless awakening.present?

    unless awakening.object_type == 'Character'
      errors.add(:awakening, "must be a character awakening")
    end
  end

  def validate_awakening_level
    if awakening_level.present? && awakening_level > 1 && awakening_id.blank?
      errors.add(:awakening_level, "cannot be set without an awakening")
    end
  end

  def validate_transcendence_requirements
    if transcendence_step.present? && transcendence_step > 0 && uncap_level < 5
      errors.add(:transcendence_step, "requires uncap level 5 (current: #{uncap_level})")
    end
  end

  def add_default_awakening
    return unless awakening.nil?

    self.awakening = Awakening.where(slug: 'character-balanced').sole
  end
end