class User < ApplicationRecord
  ROLES = %w[admin coach parent volunteer].freeze

  has_secure_password

  has_many :user_teams, dependent: :destroy
  has_many :teams, through: :user_teams
  has_many :club_memberships, dependent: :destroy
  has_many :clubs, through: :club_memberships
  has_many :owned_clubs, -> { where(club_memberships: { role: "owner" }) }, through: :club_memberships, source: :club
  has_many :stream_sessions, dependent: :nullify

  def manageable_teams
    staff_ids = teams.select(:id)
    owner_ids = Team.where(club_id: owned_clubs.select(:id)).select(:id)
    Team.where(id: staff_ids).or(Team.where(id: owner_ids))
  end

  # Squadre da cui l'utente può programmare partite e avviare lo streaming (app).
  def streamable_teams
    manageable_teams.includes(:club).select { |team| can_stream_for?(team) }
  end

  def club_admin?(club)
    club&.owned_by?(self)
  end

  def can_schedule_for?(team)
    return true if team.club&.owned_by?(self)

    membership = user_teams.find_by(team: team)
    return false if membership&.staff_kind.blank?

    membership.staff_kind == "transmission"
  end

  def schedulable_teams_for(club)
    teams = club.teams.order(:name).to_a
    return teams if club.owned_by?(self)

    teams.select { |team| can_schedule_for?(team) }
  end

  def can_stream_for?(team)
    return true if team.club&.owned_by?(self)

    membership = user_teams.find_by(team: team)
    return false if membership&.staff_kind.blank?

    return true if membership.staff_kind == "transmission"

    Teams::StaffCoverage.new(team).covers_both_roles?(membership)
  end

  def staff_role_for(team)
    return "owner" if team.club&.owned_by?(self)

    membership = user_teams.find_by(team: team)
    return nil unless membership&.staff_kind.present?

    "transmission"
  end

  def primary_club
    owned_clubs.order(:created_at).first
  end

  validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
  validates :name, presence: true
  validates :role, inclusion: { in: ROLES }

  def admin?
    role == "admin"
  end

  def generate_password_reset!
    raw = SecureRandom.urlsafe_base64(32)
    update!(
      password_reset_digest: User.digest_token(raw),
      password_reset_sent_at: Time.current
    )
    raw
  end

  def password_reset_expired?
    password_reset_sent_at.blank? ||
      password_reset_sent_at < MatchLiveTv.password_reset_expiry_hours.hours.ago
  end

  def clear_password_reset!
    update!(password_reset_digest: nil, password_reset_sent_at: nil)
  end

  def self.find_by_password_reset_token(token)
    return if token.blank?

    find_by(password_reset_digest: User.digest_token(token))
  end

  def self.digest_token(token)
    Digest::SHA256.hexdigest(token.to_s)
  end
end
