module Public
  class TeamsController < WebBaseController
    include BrandingAttachments

    before_action :require_login!
    before_action :set_club, only: %i[new create]
    before_action :set_team, only: %i[
      details dashboard roster edit update invite create_invitation
      assign_self_staff clear_self_staff remove_member destroy_invitation
    ]

    def new
      redirect_to public_new_club_path if current_user.owned_clubs.none?
      require_club_owner!(@club)
    end

    def create
      require_club_owner!(@club)
      team = @club.teams.create!(team_params)
      attach_branding_logo(team)
      redirect_to public_club_path(@club), notice: "Squadra «#{team.name}» aggiunta."
    rescue ActiveRecord::RecordInvalid => e
      flash.now[:alert] = e.record.errors.full_messages.join(", ")
      render :new, status: :unprocessable_entity
    end

    def details
      load_team_details!
      render :details
    end

    def dashboard
      redirect_to public_team_details_path(params[:id])
    end

    def roster
      redirect_to public_team_details_path(params[:id])
    end

    def edit
      require_club_owner_for_team!(@team)
      @club = @team.club
    end

    def update
      require_club_owner_for_team!(@team)
      @team.assign_attributes(team_params)
      attach_branding_logo(@team)
      attach_team_photo(@team)
      @team.save!
      redirect_to public_team_details_path(@team), notice: "Squadra aggiornata."
    rescue ActiveRecord::RecordInvalid => e
      @club = @team.club
      flash.now[:alert] = e.record.errors.full_messages.join(", ")
      render :edit, status: :unprocessable_entity
    end

    def invite
      require_club_owner_for_team!(@team)
      @entitlements = @team.entitlements
    end

    def assign_self_staff
      require_club_owner_for_team!(@team)
      membership = current_user.user_teams.find_or_initialize_by(team: @team)
      membership.role = "member" if membership.new_record?
      Teams::StaffAssignment.call(team: @team, user: current_user, membership: membership)
      redirect_to public_team_details_path(@team), notice: "Il tuo account è ora responsabile trasmissione."
    rescue Teams::StaffAssignmentError, Teams::EntitlementError => e
      redirect_to public_team_details_path(@team), alert: e.message
    end

    def clear_self_staff
      require_club_owner_for_team!(@team)
      membership = current_user.user_teams.find_by(team: @team)
      membership&.update!(staff_kind: nil)
      redirect_to public_team_details_path(@team), notice: "Ruolo staff rimosso dal tuo account."
    end

    def create_invitation
      require_club_owner_for_team!(@team)
      @entitlements = @team.entitlements
      staff_kind = "transmission"
      @entitlements.assert_can_invite!(staff_kind: staff_kind)

      email = params[:email]&.downcase&.strip
      Teams::StaffEmailValidator.assert_available!(team: @team, email: email, staff_kind: staff_kind)
      token = TeamInvitation.generate_token
      @team.team_invitations.create!(
        email: email,
        token_digest: Digest::SHA256.hexdigest(token),
        role: "member",
        staff_kind: staff_kind,
        expires_at: 7.days.from_now
      )
      @invite_url = join_public_invitation_url(token: token)
      flash.now[:notice] = "Link invito generato (valido 7 giorni)"
      render :invite
    rescue Teams::EntitlementError, Teams::StaffAssignmentError => e
      redirect_to public_team_invite_path(@team), alert: e.message
    end

    def remove_member
      require_club_owner_for_team!(@team)
      ut = @team.user_teams.find_by!(user_id: params[:user_id], role: "member")
      ut.destroy!
      redirect_to public_team_details_path(@team), notice: "Accesso revocato"
    end

    def destroy_invitation
      require_club_owner_for_team!(@team)
      inv = @team.team_invitations.pending.find(params[:invitation_id])
      inv.destroy!
      redirect_to public_team_details_path(@team), notice: "Invito annullato"
    end

    private

    def load_team_details!
      @club = @team.club
      @can_manage = @club.owned_by?(current_user)
      @entitlements = @team.entitlements
      @roster_by_category = @team.roster_by_category
      if @can_manage
        @roster_member = @team.roster_members.build(
          category: params[:category].presence_in(TeamRosterMember::CATEGORIES) || "player"
        )
      end
      @recordings = @team.recordings.ready.includes(stream_session: :match).order(created_at: :desc).limit(10)
      @owner_membership = current_user.user_teams.find_by(team: @team)
      @staff_memberships = @team.user_teams.includes(:user)
        .where("user_teams.role = 'member' OR (user_teams.staff_kind IS NOT NULL)")
      @pending_invitations = @team.team_invitations.pending.order(created_at: :desc)
    end

    def set_club
      @club = current_user.owned_clubs.find(params[:club_id])
    end

    def set_team
      @team = current_user.manageable_teams.find(params[:id])
    end

    def attach_team_photo(team)
      file = params.dig(:team, :photo_file)
      team.photo_file.attach(file) if file.present?
    end

    def team_params
      p = params.require(:team).permit(:name, :sport, :description, :logo_url, :primary_color, :secondary_color)
      p[:primary_color] = p[:primary_color].presence
      p[:secondary_color] = p[:secondary_color].presence
      if p[:primary_color].present?
        p[:primary_color] = normalize_hex_color(p[:primary_color], p[:primary_color])
      end
      if p[:secondary_color].present?
        p[:secondary_color] = normalize_hex_color(p[:secondary_color], p[:secondary_color])
      end
      p
    end
  end
end
